-
Notifications
You must be signed in to change notification settings - Fork 28
/
resolver.go
57 lines (46 loc) · 1.7 KB
/
resolver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package graphql
import (
"context"
"fmt"
"realm.pub/tavern/internal/auth"
"realm.pub/tavern/internal/ent"
"realm.pub/tavern/internal/graphql/generated"
"realm.pub/tavern/internal/graphql/models"
"github.com/99designs/gqlgen/graphql"
)
// A RepoImporter is responsible for importing tomes from the provided URL (filter based on provided filter options).
type RepoImporter interface {
Import(ctx context.Context, repo *ent.Repository, filters ...func(path string) bool) error
}
// Resolver is the resolver root.
type Resolver struct {
client *ent.Client
importer RepoImporter
}
// NewSchema creates a graphql executable schema.
func NewSchema(client *ent.Client, importer RepoImporter) graphql.ExecutableSchema {
cfg := generated.Config{
Resolvers: &Resolver{client, importer},
}
cfg.Directives.RequireRole = func(ctx context.Context, obj interface{}, next graphql.Resolver, requiredRole models.Role) (interface{}, error) {
// Allow unauthenticated contexts to continue for open endpoints
if requiredRole != models.RoleAdmin && requiredRole != models.RoleUser {
return next(ctx)
}
// Require all roles be authenticated
if !auth.IsAuthenticatedContext(ctx) {
return nil, fmt.Errorf("%w: unauthenticated", auth.ErrPermissionDenied)
}
// Require all roles be activated
if !auth.IsActivatedContext(ctx) {
return nil, fmt.Errorf("%w: unactivated", auth.ErrPermissionDenied)
}
// Require admin role have administrative privileges
if requiredRole == models.RoleAdmin && !auth.IsAdminContext(ctx) {
return nil, fmt.Errorf("%w: requires administrative privileges", auth.ErrPermissionDenied)
}
// Allow the request
return next(ctx)
}
return generated.NewExecutableSchema(cfg)
}