Files
nekoray/go/grpc_server/auth/auth.go
2023-03-04 22:20:16 +09:00

55 lines
1.4 KiB
Go

package auth
import (
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
// Authenticator exposes a function for authenticating requests.
type Authenticator struct {
Token string
}
// Authenticate checks that a token exists and is valid. It stores the user
// metadata in the returned context and removes the token from the context.
func (a Authenticator) Authenticate(ctx context.Context) (newCtx context.Context, err error) {
auth, err := extractHeader(ctx, "nekoray_auth")
if err != nil {
return ctx, err
}
if auth != a.Token {
return ctx, status.Error(codes.Unauthenticated, "invalid token")
}
return purgeHeader(ctx, "nekoray_auth"), nil
}
func extractHeader(ctx context.Context, header string) (string, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return "", status.Error(codes.Unauthenticated, "no headers in request")
}
authHeaders, ok := md[header]
if !ok {
return "", status.Error(codes.Unauthenticated, "no header in request")
}
if len(authHeaders) != 1 {
return "", status.Error(codes.Unauthenticated, "more than 1 header in request")
}
return authHeaders[0], nil
}
func purgeHeader(ctx context.Context, header string) context.Context {
md, _ := metadata.FromIncomingContext(ctx)
mdCopy := md.Copy()
mdCopy[header] = nil
return metadata.NewIncomingContext(ctx, mdCopy)
}