M auth/middleware.go => auth/middleware.go +28 -0
@@ 84,6 84,34 @@ type AuthContext struct {
TokenHash [64]byte
}
+func (authctx *AuthContext) Access(scope, kind string) error {
+ switch authctx.AuthMethod {
+ case AUTH_INTERNAL, AUTH_COOKIE:
+ return nil
+ case AUTH_OAUTH_LEGACY:
+ if kind == RO {
+ // Only legacy tokens with "*" scopes ever get this far
+ return nil
+ } else {
+ return fmt.Errorf("Read/write access denied for legacy OAuth token")
+ }
+ case AUTH_WEBHOOK:
+ if kind != RO {
+ return fmt.Errorf("Access to read/write resolver denied for webhook")
+ }
+ fallthrough
+ case AUTH_OAUTH2:
+ if !authctx.Grants.Has(scope, kind) {
+ return fmt.Errorf("Access denied, missing %v:%v grant", scope, kind)
+ }
+ return nil
+ case AUTH_ANON_INTERNAL:
+ return fmt.Errorf("Access denied for internal anonymous auth")
+ default:
+ panic(fmt.Errorf("Unknown auth method %q for access check", authctx.AuthMethod))
+ }
+}
+
func authError(w http.ResponseWriter, reason string, code int) {
gqlerr := gqlerror.Errorf("Authentication error: %s", reason)
b, err := json.Marshal(struct {
M server/directives.go => server/directives.go +3 -24
@@ 48,31 48,10 @@ func Private(ctx context.Context, obj interface{},
func Access(ctx context.Context, obj interface{}, next graphql.Resolver,
scope string, kind string) (interface{}, error) {
- authctx := auth.ForContext(ctx)
- switch authctx.AuthMethod {
- case auth.AUTH_INTERNAL, auth.AUTH_COOKIE:
- return next(ctx)
- case auth.AUTH_OAUTH_LEGACY:
- if kind == auth.RO {
- // Only legacy tokens with "*" scopes ever get this far
- return next(ctx)
- }
- case auth.AUTH_WEBHOOK:
- if kind != auth.RO {
- return nil, fmt.Errorf("Access to read/write resolver denied for webhook")
- }
- fallthrough
- case auth.AUTH_OAUTH2:
- if !authctx.Grants.Has(scope, kind) {
- return nil, fmt.Errorf("Access denied, missing %v:%v grant", scope, kind)
- }
- return next(ctx)
- case auth.AUTH_ANON_INTERNAL:
- return nil, fmt.Errorf("Access denied for internal anonymous auth")
- default:
- panic(fmt.Errorf("Unknown auth method for access check"))
+ if err := auth.ForContext(ctx).Access(scope, kind); err != nil {
+ return nil, err
}
- return nil, fmt.Errorf("Access denied for invalid auth method")
+ return next(ctx)
}