1package config
  2
  3import (
  4	"testing"
  5
  6	"github.com/charmbracelet/wish/git"
  7	"github.com/gliderlabs/ssh"
  8	"github.com/matryer/is"
  9)
 10
 11func TestAuth(t *testing.T) {
 12	adminKey := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMwLvyV3ouVrTysUYGoJdl5Vgn5BACKov+n9PlzfPwH a@b"
 13	adminPk, _, _, _, _ := ssh.ParseAuthorizedKey([]byte(adminKey))
 14	dummyKey := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxIobhwtfdwN7m1TFt9wx3PsfvcAkISGPxmbmbauST8 a@b"
 15	dummyPk, _, _, _, _ := ssh.ParseAuthorizedKey([]byte(dummyKey))
 16	cases := []struct {
 17		name   string
 18		cfg    Config
 19		repo   string
 20		key    ssh.PublicKey
 21		access git.AccessLevel
 22	}{
 23		// Repo access
 24		{
 25			name:   "anon access: no-access, anonymous user",
 26			access: git.NoAccess,
 27			repo:   "foo",
 28			cfg: Config{
 29				AnonAccess: "no-access",
 30				Repos: []RepoConfig{
 31					{
 32						Repo: "foo",
 33					},
 34				},
 35			},
 36		},
 37		{
 38			name:   "anon access: no-access, authd user",
 39			key:    dummyPk,
 40			repo:   "foo",
 41			access: git.ReadOnlyAccess,
 42			cfg: Config{
 43				AnonAccess: "no-access",
 44				Repos: []RepoConfig{
 45					{
 46						Repo: "foo",
 47					},
 48				},
 49				Users: []User{
 50					{
 51						PublicKeys: []string{
 52							dummyKey,
 53						},
 54					},
 55				},
 56			},
 57		},
 58		{
 59			name:   "anon access: no-access, admin user",
 60			repo:   "foo",
 61			key:    adminPk,
 62			access: git.AdminAccess,
 63			cfg: Config{
 64				AnonAccess: "no-access",
 65				Repos: []RepoConfig{
 66					{
 67						Repo: "foo",
 68					},
 69				},
 70				Users: []User{
 71					{
 72						Admin: true,
 73						PublicKeys: []string{
 74							adminKey,
 75						},
 76					},
 77				},
 78			},
 79		},
 80		{
 81			name:   "anon access: read-only, anonymous user",
 82			repo:   "foo",
 83			access: git.ReadOnlyAccess,
 84			cfg: Config{
 85				AnonAccess: "read-only",
 86				Repos: []RepoConfig{
 87					{
 88						Repo: "foo",
 89					},
 90				},
 91			},
 92		},
 93		{
 94			name:   "anon access: read-only, authd user",
 95			repo:   "foo",
 96			key:    dummyPk,
 97			access: git.ReadOnlyAccess,
 98			cfg: Config{
 99				AnonAccess: "read-only",
100				Repos: []RepoConfig{
101					{
102						Repo: "foo",
103					},
104				},
105				Users: []User{
106					{
107						PublicKeys: []string{
108							dummyKey,
109						},
110					},
111				},
112			},
113		},
114		{
115			name:   "anon access: read-only, admin user",
116			repo:   "foo",
117			key:    adminPk,
118			access: git.AdminAccess,
119			cfg: Config{
120				AnonAccess: "read-only",
121				Repos: []RepoConfig{
122					{
123						Repo: "foo",
124					},
125				},
126				Users: []User{
127					{
128						Admin: true,
129						PublicKeys: []string{
130							adminKey,
131						},
132					},
133				},
134			},
135		},
136		{
137			name:   "anon access: read-write, anonymous user",
138			repo:   "foo",
139			access: git.ReadWriteAccess,
140			cfg: Config{
141				AnonAccess: "read-write",
142				Repos: []RepoConfig{
143					{
144						Repo: "foo",
145					},
146				},
147			},
148		},
149		{
150			name:   "anon access: read-write, authd user",
151			repo:   "foo",
152			key:    dummyPk,
153			access: git.ReadWriteAccess,
154			cfg: Config{
155				AnonAccess: "read-write",
156				Repos: []RepoConfig{
157					{
158						Repo: "foo",
159					},
160				},
161				Users: []User{
162					{
163						PublicKeys: []string{
164							dummyKey,
165						},
166					},
167				},
168			},
169		}, {
170			name:   "anon access: read-write, admin user",
171			repo:   "foo",
172			key:    adminPk,
173			access: git.AdminAccess,
174			cfg: Config{
175				AnonAccess: "read-write",
176				Repos: []RepoConfig{
177					{
178						Repo: "foo",
179					},
180				},
181				Users: []User{
182					{
183						Admin: true,
184						PublicKeys: []string{
185							adminKey,
186						},
187					},
188				},
189			},
190		},
191		{
192			name:   "anon access: admin-access, anonymous user",
193			repo:   "foo",
194			access: git.AdminAccess,
195			cfg: Config{
196				AnonAccess: "admin-access",
197				Repos: []RepoConfig{
198					{
199						Repo: "foo",
200					},
201				},
202			},
203		},
204		{
205			name:   "anon access: admin-access, authd user",
206			repo:   "foo",
207			key:    dummyPk,
208			access: git.AdminAccess,
209			cfg: Config{
210				AnonAccess: "admin-access",
211				Repos: []RepoConfig{
212					{
213						Repo: "foo",
214					},
215				},
216				Users: []User{
217					{
218						PublicKeys: []string{
219							dummyKey,
220						},
221					},
222				},
223			},
224		}, {
225			name:   "anon access: admin-access, admin user",
226			repo:   "foo",
227			key:    adminPk,
228			access: git.AdminAccess,
229			cfg: Config{
230				AnonAccess: "admin-access",
231				Repos: []RepoConfig{
232					{
233						Repo: "foo",
234					},
235				},
236				Users: []User{
237					{
238						Admin: true,
239						PublicKeys: []string{
240							adminKey,
241						},
242					},
243				},
244			},
245		},
246
247		// Collabs
248		{
249			name:   "anon access: no-access, authd user, collab",
250			key:    dummyPk,
251			repo:   "foo",
252			access: git.ReadWriteAccess,
253			cfg: Config{
254				AnonAccess: "no-access",
255				Repos: []RepoConfig{
256					{
257						Repo: "foo",
258						Collabs: []string{
259							"user",
260						},
261					},
262				},
263				Users: []User{
264					{
265						Name: "user",
266						PublicKeys: []string{
267							dummyKey,
268						},
269					},
270				},
271			},
272		},
273		{
274			name:   "anon access: no-access, authd user, collab, private repo",
275			key:    dummyPk,
276			repo:   "foo",
277			access: git.ReadWriteAccess,
278			cfg: Config{
279				AnonAccess: "no-access",
280				Repos: []RepoConfig{
281					{
282						Repo:    "foo",
283						Private: true,
284						Collabs: []string{
285							"user",
286						},
287					},
288				},
289				Users: []User{
290					{
291						Name: "user",
292						PublicKeys: []string{
293							dummyKey,
294						},
295					},
296				},
297			},
298		},
299		{
300			name:   "anon access: no-access, admin user, collab, private repo",
301			repo:   "foo",
302			key:    adminPk,
303			access: git.AdminAccess,
304			cfg: Config{
305				AnonAccess: "no-access",
306				Repos: []RepoConfig{
307					{
308						Repo:    "foo",
309						Private: true,
310						Collabs: []string{
311							"user",
312						},
313					},
314				},
315				Users: []User{
316					{
317						Name:  "admin",
318						Admin: true,
319						PublicKeys: []string{
320							adminKey,
321						},
322					},
323				},
324			},
325		},
326		{
327			name:   "anon access: read-only, authd user, collab, private repo",
328			repo:   "foo",
329			key:    dummyPk,
330			access: git.ReadWriteAccess,
331			cfg: Config{
332				AnonAccess: "read-only",
333				Repos: []RepoConfig{
334					{
335						Repo:    "foo",
336						Private: true,
337						Collabs: []string{
338							"user",
339						},
340					},
341				},
342				Users: []User{
343					{
344						Name: "user",
345						PublicKeys: []string{
346							dummyKey,
347						},
348					},
349				},
350			},
351		},
352		{
353			name:   "anon access: admin-access, anonymous user, collab",
354			repo:   "foo",
355			access: git.AdminAccess,
356			cfg: Config{
357				AnonAccess: "admin-access",
358				Repos: []RepoConfig{
359					{
360						Repo: "foo",
361						Collabs: []string{
362							"user",
363						},
364					},
365				},
366			},
367		},
368		{
369			name:   "anon access: admin-access, authd user, collab",
370			repo:   "foo",
371			key:    dummyPk,
372			access: git.AdminAccess,
373			cfg: Config{
374				AnonAccess: "admin-access",
375				Repos: []RepoConfig{
376					{
377						Repo: "foo",
378						Collabs: []string{
379							"user",
380						},
381					},
382				},
383				Users: []User{
384					{
385						Name: "user",
386						PublicKeys: []string{
387							dummyKey,
388						},
389					},
390				},
391			},
392		}, {
393			name:   "anon access: admin-access, admin user, collab",
394			repo:   "foo",
395			key:    adminPk,
396			access: git.AdminAccess,
397			cfg: Config{
398				AnonAccess: "admin-access",
399				Repos: []RepoConfig{
400					{
401						Repo: "foo",
402						Collabs: []string{
403							"user",
404						},
405					},
406				},
407				Users: []User{
408					{
409						Name:  "admin",
410						Admin: true,
411						PublicKeys: []string{
412							adminKey,
413						},
414					},
415				},
416			},
417		},
418
419		// New repo
420		{
421			name:   "anon access: no-access, anonymous user, new repo",
422			access: git.NoAccess,
423			repo:   "foo",
424			cfg: Config{
425				AnonAccess: "no-access",
426			},
427		},
428		{
429			name:   "anon access: no-access, authd user, new repo",
430			key:    dummyPk,
431			repo:   "foo",
432			access: git.NoAccess,
433			cfg: Config{
434				AnonAccess: "no-access",
435				Users: []User{
436					{
437						PublicKeys: []string{
438							dummyKey,
439						},
440					},
441				},
442			},
443		},
444		{
445			name:   "anon access: no-access, admin user, new repo",
446			repo:   "foo",
447			key:    adminPk,
448			access: git.AdminAccess,
449			cfg: Config{
450				AnonAccess: "no-access",
451				Users: []User{
452					{
453						Admin: true,
454						PublicKeys: []string{
455							adminKey,
456						},
457					},
458				},
459			},
460		},
461		{
462			name:   "anon access: read-only, anonymous user, new repo",
463			repo:   "foo",
464			access: git.ReadOnlyAccess,
465			cfg: Config{
466				AnonAccess: "read-only",
467			},
468		},
469		{
470			name:   "anon access: read-only, authd user, new repo",
471			repo:   "foo",
472			key:    dummyPk,
473			access: git.ReadOnlyAccess,
474			cfg: Config{
475				AnonAccess: "read-only",
476				Users: []User{
477					{
478						PublicKeys: []string{
479							dummyKey,
480						},
481					},
482				},
483			},
484		},
485		{
486			name:   "anon access: read-only, admin user, new repo",
487			repo:   "foo",
488			key:    adminPk,
489			access: git.AdminAccess,
490			cfg: Config{
491				AnonAccess: "read-only",
492				Users: []User{
493					{
494						Admin: true,
495						PublicKeys: []string{
496							adminKey,
497						},
498					},
499				},
500			},
501		},
502		{
503			name:   "anon access: read-write, anonymous user, new repo",
504			repo:   "foo",
505			access: git.ReadWriteAccess,
506			cfg: Config{
507				AnonAccess: "read-write",
508			},
509		},
510		{
511			name:   "anon access: read-write, authd user, new repo",
512			repo:   "foo",
513			key:    dummyPk,
514			access: git.ReadWriteAccess,
515			cfg: Config{
516				AnonAccess: "read-write",
517				Users: []User{
518					{
519						PublicKeys: []string{
520							dummyKey,
521						},
522					},
523				},
524			},
525		},
526		{
527			name:   "anon access: read-write, admin user, new repo",
528			repo:   "foo",
529			key:    adminPk,
530			access: git.AdminAccess,
531			cfg: Config{
532				AnonAccess: "read-write",
533				Users: []User{
534					{
535						Admin: true,
536						PublicKeys: []string{
537							adminKey,
538						},
539					},
540				},
541			},
542		},
543		{
544			name:   "anon access: admin-access, anonymous user, new repo",
545			repo:   "foo",
546			access: git.AdminAccess,
547			cfg: Config{
548				AnonAccess: "admin-access",
549			},
550		},
551		{
552			name:   "anon access: admin-access, authd user, new repo",
553			repo:   "foo",
554			key:    dummyPk,
555			access: git.AdminAccess,
556			cfg: Config{
557				AnonAccess: "admin-access",
558				Users: []User{
559					{
560						PublicKeys: []string{
561							dummyKey,
562						},
563					},
564				},
565			},
566		},
567		{
568			name:   "anon access: admin-access, admin user, new repo",
569			repo:   "foo",
570			key:    adminPk,
571			access: git.AdminAccess,
572			cfg: Config{
573				AnonAccess: "admin-access",
574				Users: []User{
575					{
576						Admin: true,
577						PublicKeys: []string{
578							adminKey,
579						},
580					},
581				},
582			},
583		},
584
585		// No users
586		{
587			name:   "anon access: read-only, no users",
588			repo:   "foo",
589			access: git.ReadOnlyAccess,
590			cfg: Config{
591				AnonAccess: "read-only",
592			},
593		},
594		{
595			name:   "anon access: read-write, no users",
596			repo:   "foo",
597			access: git.ReadWriteAccess,
598			cfg: Config{
599				AnonAccess: "read-write",
600			},
601		},
602	}
603	for _, c := range cases {
604		t.Run(c.name, func(t *testing.T) {
605			is := is.New(t)
606			al := c.cfg.accessForKey(c.repo, c.key)
607			is.Equal(al, c.access)
608		})
609	}
610}