auth_test.go

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