package authz import ( "context" "fmt" "net/http" "net/http/httptest" "testing" "git.ofmax.li/go-git-server/internal/admin" "github.com/casbin/casbin/v2" ) func junkTestHandler() http.HandlerFunc { return func(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusOK) } } func TestAuthentication(t *testing.T) { badToken, _, _ := GenerateNewToken() token, hash, _ := GenerateNewToken() okUserName := "tester" badUserName := "badb00" tm := TokenMap{} tm["uid:tester"] = hash cases := []struct { description string username string token string tm TokenMap statusCode int handler http.HandlerFunc }{ { username: okUserName, token: token, tm: tm, statusCode: http.StatusOK, description: "Good Login", handler: func(rw http.ResponseWriter, req *http.Request) { ctx := req.Context() uid := ctx.Value("urn") if uid != fmt.Sprintf("uid:%s", okUserName) { t.Fatal("Context UID not set") } }, }, { username: badUserName, token: token, tm: tm, statusCode: http.StatusForbidden, description: "Bad usename", handler: junkTestHandler(), }, { username: okUserName, token: badToken, tm: tm, statusCode: http.StatusForbidden, description: "Bad token", handler: junkTestHandler(), }, } for _, tc := range cases { authHandler := Authentication(tc.tm, tc.handler) req := httptest.NewRequest(http.MethodGet, "https://git.ofmax.li", nil) req.SetBasicAuth(tc.username, tc.token) recorder := httptest.NewRecorder() authHandler.ServeHTTP(recorder, req) result := recorder.Result() if result.StatusCode != tc.statusCode { t.Fatalf("Test Case %s failed Expected: %d Found: %d", tc.description, tc.statusCode, result.StatusCode) } t.Logf("Test Case: %s Expected: %d Found: %d", tc.description, tc.statusCode, result.StatusCode) } } func TestAuthorization(t *testing.T) { t.Log("Starting authorization tests") baseURL := "http://test" enf, err := casbin.NewSyncedEnforcer("../../auth_model.ini", "../../testpolicy.csv") if err != nil { t.Fatalf("Failed to load policies\n%s", err) } cases := []struct { url string user string expectedStatus int description string }{ { url: fmt.Sprintf("%s/%s", baseURL, "repo/url"), user: "uid:jack", expectedStatus: 200, description: "an autorized action should yield a 200", }, { url: fmt.Sprintf("%s/%s", baseURL, "repo/url/bar"), user: "uid:chumba", expectedStatus: 403, description: "an unautorized action should yield a 403", }, } svcr := &admin.Servicer{ enf, &admin.ServerRepos{}, } for _, tc := range cases { t.Logf("test case: %s", tc.description) authHandler := Authorization(svcr, junkTestHandler()) recorder := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, tc.url, nil) ctx := req.Context() ctx = context.WithValue(ctx, "urn", tc.user) req = req.WithContext(ctx) authHandler.ServeHTTP(recorder, req) result := recorder.Result() if result.StatusCode != tc.expectedStatus { t.Fatalf("Test Case failed Expected: %d Found: %d", tc.expectedStatus, result.StatusCode) } } }