diff --git a/cmd/omegaup-gitserver/auth.go b/cmd/omegaup-gitserver/auth.go index 2d4c433..fc93f6f 100644 --- a/cmd/omegaup-gitserver/auth.go +++ b/cmd/omegaup-gitserver/auth.go @@ -142,8 +142,8 @@ func (a *omegaupAuthorization) parseUsernameAndPassword( return } - if username == "omegaup:system" { - // omegaup:system can only log in using the auth token or the secret token. + if strings.HasPrefix(username, "omegaup:") { + // omegaup:system and friends can only log in using the auth token or the secret token. a.log.Error( "user tried to login with restricted user", map[string]interface{}{ @@ -231,13 +231,15 @@ func (a *omegaupAuthorization) parseAuthorizationHeader( } } - if a.config.Gitserver.AllowSecretTokenAuthentication && a.config.Gitserver.SecretToken != "" { - if strings.EqualFold(tokens[0], omegaUpSharedSecretAuthenticationScheme) { + if a.config.Gitserver.AllowSecretTokenAuthentication && + strings.EqualFold(tokens[0], omegaUpSharedSecretAuthenticationScheme) { + if a.config.Gitserver.SecretToken != "" || a.config.Gitserver.GraderSecretToken != "" { if len(tokens) != 3 { return } - if tokens[1] != a.config.Gitserver.SecretToken { + if (tokens[1] != a.config.Gitserver.SecretToken) && + (tokens[1] != a.config.Gitserver.GraderSecretToken || tokens[2] != "omegaup:grader") { return } @@ -388,18 +390,25 @@ func (a *omegaupAuthorization) authorize( // This is a legit health check, so we grant privileges to the test problem. requestContext.Request.CanView = true requestContext.Request.CanEdit = true + requestContext.Request.CanViewAllRefs = true + } else if username == "omegaup:grader" || *insecureSkipAuthorization { + // This is the grader, it has read-only privileges for all problems. + requestContext.Request.CanView = true + requestContext.Request.CanViewAllRefs = true } else if username == "omegaup:system" || *insecureSkipAuthorization { // This is the frontend, and we trust it completely. requestContext.Request.IsSystem = true requestContext.Request.IsAdmin = true requestContext.Request.CanView = true requestContext.Request.CanEdit = true + requestContext.Request.CanViewAllRefs = true } else if requestContext.Request.Create { // This is a repository creation request. There is nothing in the database // yet, so grant them all privileges. requestContext.Request.IsAdmin = true requestContext.Request.CanView = true requestContext.Request.CanEdit = true + requestContext.Request.CanViewAllRefs = true } else { auth, err := a.getAuthorizationFromFrontend( username, @@ -421,6 +430,7 @@ func (a *omegaupAuthorization) authorize( requestContext.Request.IsAdmin = auth.IsAdmin requestContext.Request.CanView = auth.CanView requestContext.Request.CanEdit = auth.CanEdit + requestContext.Request.CanViewAllRefs = auth.CanEdit } a.log.Info( "Auth", diff --git a/cmd/omegaup-gitserver/config.go b/cmd/omegaup-gitserver/config.go index 993bc8e..9abee99 100644 --- a/cmd/omegaup-gitserver/config.go +++ b/cmd/omegaup-gitserver/config.go @@ -37,6 +37,10 @@ type GitserverConfig struct { // authenticate instead of using PKI, in both directions. SecretToken string + // GraderSecretToken is a shared secret with the grader that can be used to + // authenticate instead of using PKI, in both directions. + GraderSecretToken string + // AllowSecretTokenAuthentication controls whether the SecretToken can be // used to authenticate incoming requests, instead of just being used for // outgoing requests towards the frontend. @@ -84,6 +88,7 @@ var defaultConfig = Config{ RootPath: "/var/lib/omegaup/problems.git", PublicKey: "gKEg5JlIOA1BsIxETZYhjd+ZGchY/rZeQM0GheAWvXw=", SecretToken: "", + GraderSecretToken: "", Port: 33861, PprofPort: 33862, LibinteractivePath: "/usr/share/java/libinteractive.jar", diff --git a/cmd/omegaup-gitserver/main.go b/cmd/omegaup-gitserver/main.go index de86b2a..ca5d718 100644 --- a/cmd/omegaup-gitserver/main.go +++ b/cmd/omegaup-gitserver/main.go @@ -49,7 +49,7 @@ func referenceDiscovery( referenceName string, ) bool { requestContext := request.FromContext(ctx) - if requestContext.Request.CanEdit { + if requestContext.Request.CanViewAllRefs { return true } if requestContext.Request.HasSolved { diff --git a/request/request.go b/request/request.go index 0aa37f9..0c1fc34 100644 --- a/request/request.go +++ b/request/request.go @@ -14,15 +14,16 @@ const requestContextKey key = 0 // Request stores the request-specific part of the Context, to make it easier // to serialize. type Request struct { - ProblemName string - Username string - Create bool - IsSystem bool - IsAdmin bool - CanView bool - CanEdit bool - HasSolved bool - ReviewRef string + ProblemName string + Username string + Create bool + IsSystem bool + IsAdmin bool + CanView bool + CanViewAllRefs bool + CanEdit bool + HasSolved bool + ReviewRef string } // Context stores a few variables that are request-specific.