diff --git a/server/auth.go b/server/auth.go index fb2ccd967..5b35f72ed 100644 --- a/server/auth.go +++ b/server/auth.go @@ -292,13 +292,17 @@ func handleLoginFromHeaders(ds model.DataStore, r *http.Request) map[string]inte user, err := userRepo.FindByUsernameWithPassword(username) if user == nil || err != nil { log.Info(r, "User passed in header not found", "user", username) + // Check if this is the first user being created + count, _ := userRepo.CountAll() + isFirstUser := count == 0 + newUser := model.User{ ID: id.NewRandom(), UserName: username, Name: username, Email: "", NewPassword: consts.PasswordAutogenPrefix + id.NewRandom(), - IsAdmin: false, + IsAdmin: isFirstUser, // Make the first user an admin } err := userRepo.Put(&newUser) if err != nil { diff --git a/server/auth_test.go b/server/auth_test.go index 0d4236d53..06ca2ea39 100644 --- a/server/auth_test.go +++ b/server/auth_test.go @@ -292,4 +292,54 @@ var _ = Describe("Auth", func() { }) }) }) + + Describe("handleLoginFromHeaders", func() { + var ds model.DataStore + var req *http.Request + const trustedIP = "192.168.0.42" + + BeforeEach(func() { + ds = &tests.MockDataStore{} + req = httptest.NewRequest("GET", "/", nil) + req = req.WithContext(request.WithReverseProxyIp(req.Context(), trustedIP)) + conf.Server.ReverseProxyWhitelist = "192.168.0.0/16" + conf.Server.ReverseProxyUserHeader = "Remote-User" + }) + + It("makes the first user an admin", func() { + // No existing users + req.Header.Set("Remote-User", "firstuser") + result := handleLoginFromHeaders(ds, req) + + Expect(result).ToNot(BeNil()) + Expect(result["isAdmin"]).To(BeTrue()) + + // Verify user was created as admin + u, err := ds.User(context.Background()).FindByUsername("firstuser") + Expect(err).To(BeNil()) + Expect(u.IsAdmin).To(BeTrue()) + }) + + It("does not make subsequent users admins", func() { + // Create the first user + _ = ds.User(context.Background()).Put(&model.User{ + ID: "existing-user-id", + UserName: "existinguser", + Name: "Existing User", + IsAdmin: true, + }) + + // Try to create a second user via proxy header + req.Header.Set("Remote-User", "seconduser") + result := handleLoginFromHeaders(ds, req) + + Expect(result).ToNot(BeNil()) + Expect(result["isAdmin"]).To(BeFalse()) + + // Verify user was created as non-admin + u, err := ds.User(context.Background()).FindByUsername("seconduser") + Expect(err).To(BeNil()) + Expect(u.IsAdmin).To(BeFalse()) + }) + }) })