Basic Auth Context

This commit is contained in:
2021-02-02 22:55:35 -05:00
parent 7e6454c593
commit c39fe6ec24
13 changed files with 828 additions and 202 deletions

View File

@@ -42,8 +42,8 @@ type ResolverRoot interface {
}
type DirectiveRoot struct {
HasRole func(ctx context.Context, obj interface{}, next graphql.Resolver, role model.Role) (res interface{}, err error)
Meta func(ctx context.Context, obj interface{}, next graphql.Resolver, gorm *string) (res interface{}, err error)
HasMinRole func(ctx context.Context, obj interface{}, next graphql.Resolver, role model.Role) (res interface{}, err error)
Meta func(ctx context.Context, obj interface{}, next graphql.Resolver, gorm *string) (res interface{}, err error)
}
type ComplexityRoot struct {
@@ -59,6 +59,11 @@ type ComplexityRoot struct {
PageInfo func(childComplexity int) int
}
AuthResponse struct {
Error func(childComplexity int) int
Result func(childComplexity int) int
}
Device struct {
CreatedAt func(childComplexity int) int
ID func(childComplexity int) int
@@ -113,6 +118,9 @@ type ComplexityRoot struct {
Albums func(childComplexity int, filter *model.AlbumFilter, count *int, page *int) int
Device func(childComplexity int, id string) int
Devices func(childComplexity int, filter *model.DeviceFilter, count *int, page *int) int
Login func(childComplexity int, user string, password string) int
Logout func(childComplexity int) int
Me func(childComplexity int) int
MediaItem func(childComplexity int, id string) int
MediaItems func(childComplexity int, filter *model.MediaItemFilter, count *int, page *int) int
Tag func(childComplexity int, id string) int
@@ -160,11 +168,14 @@ type MutationResolver interface {
CreateUser(ctx context.Context, input model.NewUser) (*model.User, error)
}
type QueryResolver interface {
Login(ctx context.Context, user string, password string) (model.AuthResult, error)
Logout(ctx context.Context) (model.AuthResult, error)
MediaItem(ctx context.Context, id string) (*model.MediaItem, error)
Device(ctx context.Context, id string) (*model.Device, error)
Album(ctx context.Context, id string) (*model.Album, error)
Tag(ctx context.Context, id string) (*model.Tag, error)
User(ctx context.Context, id string) (*model.User, error)
Tag(ctx context.Context, id string) (*model.Tag, error)
Me(ctx context.Context) (*model.User, error)
MediaItems(ctx context.Context, filter *model.MediaItemFilter, count *int, page *int) (*model.MediaItemResponse, error)
Devices(ctx context.Context, filter *model.DeviceFilter, count *int, page *int) (*model.DeviceResponse, error)
Albums(ctx context.Context, filter *model.AlbumFilter, count *int, page *int) (*model.AlbumResponse, error)
@@ -229,6 +240,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.AlbumResponse.PageInfo(childComplexity), true
case "AuthResponse.Error":
if e.complexity.AuthResponse.Error == nil {
break
}
return e.complexity.AuthResponse.Error(childComplexity), true
case "AuthResponse.Result":
if e.complexity.AuthResponse.Result == nil {
break
}
return e.complexity.AuthResponse.Result(childComplexity), true
case "Device.createdAt":
if e.complexity.Device.CreatedAt == nil {
break
@@ -519,6 +544,32 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Query.Devices(childComplexity, args["filter"].(*model.DeviceFilter), args["count"].(*int), args["page"].(*int)), true
case "Query.login":
if e.complexity.Query.Login == nil {
break
}
args, err := ec.field_Query_login_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.Login(childComplexity, args["user"].(string), args["password"].(string)), true
case "Query.logout":
if e.complexity.Query.Logout == nil {
break
}
return e.complexity.Query.Logout(childComplexity), true
case "Query.me":
if e.complexity.Query.Me == nil {
break
}
return e.complexity.Query.Me(childComplexity), true
case "Query.mediaItem":
if e.complexity.Query.MediaItem == nil {
break
@@ -787,7 +838,7 @@ scalar Time
scalar Upload
# https://gqlgen.com/reference/directives/
directive @hasRole(role: Role!) on FIELD_DEFINITION
directive @hasMinRole(role: Role!) on FIELD_DEFINITION
directive @meta(
gorm: String,
@@ -814,6 +865,20 @@ enum AuthType {
LDAP
}
# ------------------------------------------------------------
# ---------------------- Authentication ----------------------
# ------------------------------------------------------------
enum AuthResult {
Success
Failure
}
type AuthResponse {
Result: AuthResult!
Error: String
}
# ------------------------------------------------------------
# ----------------------- Type Filters -----------------------
# ------------------------------------------------------------
@@ -1095,47 +1160,56 @@ type AlbumResponse {
# ------------------------------------------------------------
type Query {
# Authentication
login(
user: String!
password: String!
): AuthResult!
logout: AuthResult! @hasMinRole(role: User)
# Single Item
mediaItem(id: ID!): MediaItem! @hasRole(role: User)
device(id: ID!): Device! @hasRole(role: User)
album(id: ID!): Album! @hasRole(role: User)
tag(id: ID!): Tag! @hasRole(role: User)
user(id: ID!): User! @hasRole(role: Admin)
mediaItem(id: ID!): MediaItem! @hasMinRole(role: User)
device(id: ID!): Device! @hasMinRole(role: User)
album(id: ID!): Album! @hasMinRole(role: User)
user(id: ID!): User! @hasMinRole(role: Admin)
tag(id: ID!): Tag! @hasMinRole(role: User)
me: User! @hasMinRole(role: User)
# All
mediaItems(
filter: MediaItemFilter
count: Int
page: Int
): MediaItemResponse! @hasRole(role: User)
): MediaItemResponse! @hasMinRole(role: User)
devices(
filter: DeviceFilter
count: Int
page: Int
): DeviceResponse! @hasRole(role: User)
): DeviceResponse! @hasMinRole(role: User)
albums(
filter: AlbumFilter
count: Int
page: Int
): AlbumResponse! @hasRole(role: User)
): AlbumResponse! @hasMinRole(role: User)
tags(
filter: TagFilter
count: Int
page: Int
): TagResponse! @hasRole(role: User)
): TagResponse! @hasMinRole(role: User)
users(
filter: UserFilter
count: Int
page: Int
): UserResponse! @hasRole(role: Admin)
): UserResponse! @hasMinRole(role: Admin)
}
type Mutation {
createMediaItem(input: NewMediaItem!): MediaItem! @hasRole(role: User)
createDevice(input: NewDevice!): Device! @hasRole(role: User)
createAlbum(input: NewAlbum!): Album! @hasRole(role: User)
createTag(input: NewTag!): Tag! @hasRole(role: User)
createUser(input: NewUser!): User! @hasRole(role: Admin)
createMediaItem(input: NewMediaItem!): MediaItem! @hasMinRole(role: User)
createDevice(input: NewDevice!): Device! @hasMinRole(role: User)
createAlbum(input: NewAlbum!): Album! @hasMinRole(role: User)
createTag(input: NewTag!): Tag! @hasMinRole(role: User)
createUser(input: NewUser!): User! @hasMinRole(role: Admin)
}
`, BuiltIn: false},
}
@@ -1145,7 +1219,7 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...)
// region ***************************** args.gotpl *****************************
func (ec *executionContext) dir_hasRole_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
func (ec *executionContext) dir_hasMinRole_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 model.Role
@@ -1361,6 +1435,30 @@ func (ec *executionContext) field_Query_devices_args(ctx context.Context, rawArg
return args, nil
}
func (ec *executionContext) field_Query_login_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["user"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("user"))
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["user"] = arg0
var arg1 string
if tmp, ok := rawArgs["password"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("password"))
arg1, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["password"] = arg1
return args, nil
}
func (ec *executionContext) field_Query_mediaItem_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -1789,6 +1887,73 @@ func (ec *executionContext) _AlbumResponse_pageInfo(ctx context.Context, field g
return ec.marshalNPageInfo2ᚖreichardᚗioᚋimaginiᚋgraphᚋmodelᚐPageInfo(ctx, field.Selections, res)
}
func (ec *executionContext) _AuthResponse_Result(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
Args: nil,
IsMethod: false,
IsResolver: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Result, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(model.AuthResult)
fc.Result = res
return ec.marshalNAuthResult2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐAuthResult(ctx, field.Selections, res)
}
func (ec *executionContext) _AuthResponse_Error(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
Args: nil,
IsMethod: false,
IsResolver: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Error, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) _Device_id(ctx context.Context, field graphql.CollectedField, obj *model.Device) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@@ -2843,10 +3008,10 @@ func (ec *executionContext) _Mutation_createMediaItem(ctx context.Context, field
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -2909,10 +3074,10 @@ func (ec *executionContext) _Mutation_createDevice(ctx context.Context, field gr
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -2975,10 +3140,10 @@ func (ec *executionContext) _Mutation_createAlbum(ctx context.Context, field gra
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3041,10 +3206,10 @@ func (ec *executionContext) _Mutation_createTag(ctx context.Context, field graph
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3107,10 +3272,10 @@ func (ec *executionContext) _Mutation_createUser(ctx context.Context, field grap
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3245,6 +3410,107 @@ func (ec *executionContext) _PageInfo_total(ctx context.Context, field graphql.C
return ec.marshalNInt2int(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_login(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_login_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Login(rctx, args["user"].(string), args["password"].(string))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(model.AuthResult)
fc.Result = res
return ec.marshalNAuthResult2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐAuthResult(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_logout(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Logout(rctx)
}
directive1 := func(ctx context.Context) (interface{}, error) {
role, err := ec.unmarshalNRole2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐRole(ctx, "User")
if err != nil {
return nil, err
}
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(model.AuthResult); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be reichard.io/imagini/graph/model.AuthResult`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(model.AuthResult)
fc.Result = res
return ec.marshalNAuthResult2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐAuthResult(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_mediaItem(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@@ -3278,10 +3544,10 @@ func (ec *executionContext) _Query_mediaItem(ctx context.Context, field graphql.
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3344,10 +3610,10 @@ func (ec *executionContext) _Query_device(ctx context.Context, field graphql.Col
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3410,10 +3676,10 @@ func (ec *executionContext) _Query_album(ctx context.Context, field graphql.Coll
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3443,72 +3709,6 @@ func (ec *executionContext) _Query_album(ctx context.Context, field graphql.Coll
return ec.marshalNAlbum2ᚖreichardᚗioᚋimaginiᚋgraphᚋmodelᚐAlbum(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_tag(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_tag_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Tag(rctx, args["id"].(string))
}
directive1 := func(ctx context.Context) (interface{}, error) {
role, err := ec.unmarshalNRole2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐRole(ctx, "User")
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*model.Tag); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *reichard.io/imagini/graph/model.Tag`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*model.Tag)
fc.Result = res
return ec.marshalNTag2ᚖreichardᚗioᚋimaginiᚋgraphᚋmodelᚐTag(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@@ -3542,10 +3742,135 @@ func (ec *executionContext) _Query_user(ctx context.Context, field graphql.Colle
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*model.User); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *reichard.io/imagini/graph/model.User`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*model.User)
fc.Result = res
return ec.marshalNUser2ᚖreichardᚗioᚋimaginiᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_tag(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_tag_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Tag(rctx, args["id"].(string))
}
directive1 := func(ctx context.Context) (interface{}, error) {
role, err := ec.unmarshalNRole2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐRole(ctx, "User")
if err != nil {
return nil, err
}
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, graphql.ErrorOnPath(ctx, err)
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*model.Tag); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *reichard.io/imagini/graph/model.Tag`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*model.Tag)
fc.Result = res
return ec.marshalNTag2ᚖreichardᚗioᚋimaginiᚋgraphᚋmodelᚐTag(ctx, field.Selections, res)
}
func (ec *executionContext) _Query_me(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
IsResolver: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Me(rctx)
}
directive1 := func(ctx context.Context) (interface{}, error) {
role, err := ec.unmarshalNRole2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐRole(ctx, "User")
if err != nil {
return nil, err
}
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3608,10 +3933,10 @@ func (ec *executionContext) _Query_mediaItems(ctx context.Context, field graphql
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3674,10 +3999,10 @@ func (ec *executionContext) _Query_devices(ctx context.Context, field graphql.Co
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3740,10 +4065,10 @@ func (ec *executionContext) _Query_albums(ctx context.Context, field graphql.Col
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3806,10 +4131,10 @@ func (ec *executionContext) _Query_tags(ctx context.Context, field graphql.Colle
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -3872,10 +4197,10 @@ func (ec *executionContext) _Query_users(ctx context.Context, field graphql.Coll
if err != nil {
return nil, err
}
if ec.directives.HasRole == nil {
return nil, errors.New("directive hasRole is not implemented")
if ec.directives.HasMinRole == nil {
return nil, errors.New("directive hasMinRole is not implemented")
}
return ec.directives.HasRole(ctx, nil, directive0, role)
return ec.directives.HasMinRole(ctx, nil, directive0, role)
}
tmp, err := directive1(rctx)
@@ -7006,6 +7331,35 @@ func (ec *executionContext) _AlbumResponse(ctx context.Context, sel ast.Selectio
return out
}
var authResponseImplementors = []string{"AuthResponse"}
func (ec *executionContext) _AuthResponse(ctx context.Context, sel ast.SelectionSet, obj *model.AuthResponse) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, authResponseImplementors)
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("AuthResponse")
case "Result":
out.Values[i] = ec._AuthResponse_Result(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "Error":
out.Values[i] = ec._AuthResponse_Error(ctx, field, obj)
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var deviceImplementors = []string{"Device"}
func (ec *executionContext) _Device(ctx context.Context, sel ast.SelectionSet, obj *model.Device) graphql.Marshaler {
@@ -7264,6 +7618,34 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("Query")
case "login":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_login(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "logout":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_logout(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "mediaItem":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
@@ -7306,6 +7688,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
}
return res
})
case "user":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_user(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "tag":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
@@ -7320,7 +7716,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
}
return res
})
case "user":
case "me":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
@@ -7328,7 +7724,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_user(ctx, field)
res = ec._Query_me(ctx, field)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
@@ -7837,6 +8233,16 @@ func (ec *executionContext) marshalNAlbumResponse2ᚖreichardᚗioᚋimaginiᚋg
return ec._AlbumResponse(ctx, sel, v)
}
func (ec *executionContext) unmarshalNAuthResult2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐAuthResult(ctx context.Context, v interface{}) (model.AuthResult, error) {
var res model.AuthResult
err := res.UnmarshalGQL(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNAuthResult2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐAuthResult(ctx context.Context, sel ast.SelectionSet, v model.AuthResult) graphql.Marshaler {
return v
}
func (ec *executionContext) unmarshalNAuthType2reichardᚗioᚋimaginiᚋgraphᚋmodelᚐAuthType(ctx context.Context, v interface{}) (model.AuthType, error) {
var res model.AuthType
err := res.UnmarshalGQL(v)

View File

@@ -0,0 +1,12 @@
package model
import (
"net/http"
)
type AuthContext struct {
AccessToken string
RefreshToken string
AuthResponse *http.ResponseWriter
AuthRequest *http.Request
}

36
graph/model/models_db.go Normal file
View File

@@ -0,0 +1,36 @@
package model
import (
"gorm.io/gorm"
"github.com/google/uuid"
)
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
newID := uuid.New().String()
u.ID = &newID
return
}
func (a *Album) BeforeCreate(tx *gorm.DB) (err error) {
newID := uuid.New().String()
a.ID = &newID
return
}
func (m *MediaItem) BeforeCreate(tx *gorm.DB) (err error) {
newID := uuid.New().String()
m.ID = &newID
return
}
func (t *Tag) BeforeCreate(tx *gorm.DB) (err error) {
newID := uuid.New().String()
t.ID = &newID
return
}
func (d *Device) BeforeCreate(tx *gorm.DB) (err error) {
newID := uuid.New().String()
d.ID = &newID
return
}

View File

@@ -32,6 +32,11 @@ type AlbumResponse struct {
PageInfo *PageInfo `json:"pageInfo" `
}
type AuthResponse struct {
Result AuthResult `json:"Result" `
Error *string `json:"Error" `
}
type AuthTypeFilter struct {
EqualTo *AuthType `json:"equalTo" `
NotEqualTo *AuthType `json:"notEqualTo" `
@@ -261,6 +266,47 @@ type UserResponse struct {
PageInfo *PageInfo `json:"pageInfo" `
}
type AuthResult string
const (
AuthResultSuccess AuthResult = "Success"
AuthResultFailure AuthResult = "Failure"
)
var AllAuthResult = []AuthResult{
AuthResultSuccess,
AuthResultFailure,
}
func (e AuthResult) IsValid() bool {
switch e {
case AuthResultSuccess, AuthResultFailure:
return true
}
return false
}
func (e AuthResult) String() string {
return string(e)
}
func (e *AuthResult) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}
*e = AuthResult(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid AuthResult", str)
}
return nil
}
func (e AuthResult) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}
type AuthType string
const (

View File

@@ -4,7 +4,7 @@ scalar Time
scalar Upload
# https://gqlgen.com/reference/directives/
directive @hasRole(role: Role!) on FIELD_DEFINITION
directive @hasMinRole(role: Role!) on FIELD_DEFINITION
directive @meta(
gorm: String,
@@ -31,6 +31,20 @@ enum AuthType {
LDAP
}
# ------------------------------------------------------------
# ---------------------- Authentication ----------------------
# ------------------------------------------------------------
enum AuthResult {
Success
Failure
}
type AuthResponse {
Result: AuthResult!
Error: String
}
# ------------------------------------------------------------
# ----------------------- Type Filters -----------------------
# ------------------------------------------------------------
@@ -312,45 +326,54 @@ type AlbumResponse {
# ------------------------------------------------------------
type Query {
# Authentication
login(
user: String!
password: String!
): AuthResult!
logout: AuthResult! @hasMinRole(role: User)
# Single Item
mediaItem(id: ID!): MediaItem! @hasRole(role: User)
device(id: ID!): Device! @hasRole(role: User)
album(id: ID!): Album! @hasRole(role: User)
tag(id: ID!): Tag! @hasRole(role: User)
user(id: ID!): User! @hasRole(role: Admin)
mediaItem(id: ID!): MediaItem! @hasMinRole(role: User)
device(id: ID!): Device! @hasMinRole(role: User)
album(id: ID!): Album! @hasMinRole(role: User)
user(id: ID!): User! @hasMinRole(role: Admin)
tag(id: ID!): Tag! @hasMinRole(role: User)
me: User! @hasMinRole(role: User)
# All
mediaItems(
filter: MediaItemFilter
count: Int
page: Int
): MediaItemResponse! @hasRole(role: User)
): MediaItemResponse! @hasMinRole(role: User)
devices(
filter: DeviceFilter
count: Int
page: Int
): DeviceResponse! @hasRole(role: User)
): DeviceResponse! @hasMinRole(role: User)
albums(
filter: AlbumFilter
count: Int
page: Int
): AlbumResponse! @hasRole(role: User)
): AlbumResponse! @hasMinRole(role: User)
tags(
filter: TagFilter
count: Int
page: Int
): TagResponse! @hasRole(role: User)
): TagResponse! @hasMinRole(role: User)
users(
filter: UserFilter
count: Int
page: Int
): UserResponse! @hasRole(role: Admin)
): UserResponse! @hasMinRole(role: Admin)
}
type Mutation {
createMediaItem(input: NewMediaItem!): MediaItem! @hasRole(role: User)
createDevice(input: NewDevice!): Device! @hasRole(role: User)
createAlbum(input: NewAlbum!): Album! @hasRole(role: User)
createTag(input: NewTag!): Tag! @hasRole(role: User)
createUser(input: NewUser!): User! @hasRole(role: Admin)
createMediaItem(input: NewMediaItem!): MediaItem! @hasMinRole(role: User)
createDevice(input: NewDevice!): Device! @hasMinRole(role: User)
createAlbum(input: NewAlbum!): Album! @hasMinRole(role: User)
createTag(input: NewTag!): Tag! @hasMinRole(role: User)
createUser(input: NewUser!): User! @hasMinRole(role: Admin)
}

View File

@@ -4,6 +4,7 @@ package graph
// will be copied through when generating and any unknown code will be moved to the end.
import (
"net/http"
"context"
"fmt"
@@ -28,7 +29,38 @@ func (r *mutationResolver) CreateTag(ctx context.Context, input model.NewTag) (*
}
func (r *mutationResolver) CreateUser(ctx context.Context, input model.NewUser) (*model.User, error) {
panic(fmt.Errorf("not implemented"))
user := &model.User{
Email: input.Email,
Username: input.Username,
FirstName: input.FirstName,
LastName: input.LastName,
Role: input.Role,
AuthType: input.AuthType,
Password: input.Password,
}
err := r.DB.CreateUser(user)
if err != nil {
panic(fmt.Errorf("DB Error"))
}
return user, nil
}
func (r *queryResolver) Login(ctx context.Context, user string, password string) (model.AuthResult, error) {
// Set Cookie From Context
authContext := ctx.Value("auth").(*model.AuthContext)
resp := *authContext.AuthResponse
testCookie := http.Cookie{Name: "TestCookie", Value: "Test123", Path: "/", HttpOnly: true}
http.SetCookie(resp, &testCookie)
return model.AuthResultSuccess, nil
}
func (r *queryResolver) Logout(ctx context.Context) (model.AuthResult, error) {
// panic(fmt.Errorf("not implemented"))
return model.AuthResultSuccess, nil
}
func (r *queryResolver) MediaItem(ctx context.Context, id string) (*model.MediaItem, error) {
@@ -43,11 +75,15 @@ func (r *queryResolver) Album(ctx context.Context, id string) (*model.Album, err
panic(fmt.Errorf("not implemented"))
}
func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) {
panic(fmt.Errorf("not implemented"))
}
func (r *queryResolver) Tag(ctx context.Context, id string) (*model.Tag, error) {
panic(fmt.Errorf("not implemented"))
}
func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) {
func (r *queryResolver) Me(ctx context.Context) (*model.User, error) {
panic(fmt.Errorf("not implemented"))
}
@@ -68,7 +104,18 @@ func (r *queryResolver) Tags(ctx context.Context, filter *model.TagFilter, count
}
func (r *queryResolver) Users(ctx context.Context, filter *model.UserFilter, count *int, page *int) (*model.UserResponse, error) {
panic(fmt.Errorf("not implemented"))
resp, totalCount, err := r.DB.Users()
if err != nil {
panic(fmt.Errorf("DB Error"))
}
return &model.UserResponse{
Data: resp,
PageInfo: &model.PageInfo{
Count: int(totalCount),
Page: 0,
Total: int(totalCount),
},
}, nil
}
// Mutation returns generated.MutationResolver implementation.