diff options
author | Jacob Vosmaer (GitLab) <jacob@gitlab.com> | 2018-04-11 16:14:53 +0300 |
---|---|---|
committer | Zeger-Jan van de Weg <zegerjan@gitlab.com> | 2018-04-11 16:14:53 +0300 |
commit | ca1f9fc86f7f301dc9dbb8245180de8460d87c06 (patch) | |
tree | 96e66c7b77add9ae0eb0955d4a36dc545d4f43e4 /auth/token.go | |
parent | 4670e7da8549506752627357bb05ad62332274c9 (diff) |
Make more of the auth code public so we can reuse it
Diffstat (limited to 'auth/token.go')
-rw-r--r-- | auth/token.go | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/auth/token.go b/auth/token.go new file mode 100644 index 000000000..fc13c5bee --- /dev/null +++ b/auth/token.go @@ -0,0 +1,45 @@ +package gitalyauth + +import ( + "crypto/subtle" + "encoding/base64" + + "github.com/grpc-ecosystem/go-grpc-middleware/auth" + "golang.org/x/net/context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var ( + errUnauthenticated = status.Errorf(codes.Unauthenticated, "authentication required") + errDenied = status.Errorf(codes.PermissionDenied, "permission denied") +) + +// CheckToken checks the 'authentication' header of incoming gRPC +// metadata in ctx. It returns nil if and only if the token matches +// secret. +func CheckToken(ctx context.Context, secret string) error { + if len(secret) == 0 { + panic("CheckToken: secret may not be empty") + } + + encodedToken, err := grpc_auth.AuthFromMD(ctx, "bearer") + if err != nil { + return errUnauthenticated + } + + token, err := base64.StdEncoding.DecodeString(encodedToken) + if err != nil { + return errUnauthenticated + } + + if !tokensEqual(token, []byte(secret)) { + return errDenied + } + + return nil +} + +func tokensEqual(tok1, tok2 []byte) bool { + return subtle.ConstantTimeCompare(tok1, tok2) == 1 +} |