mirror of
https://github.com/Unkn0wnCat/matrix-veles.git
synced 2025-07-27 05:17:42 +02:00
api: Update graphql schema
This commit is contained in:
parent
8256b70fcb
commit
39f721101e
9 changed files with 1955 additions and 89 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,10 @@
|
||||||
package graph
|
package graph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
"github.com/Unkn0wnCat/matrix-veles/graph/model"
|
"github.com/Unkn0wnCat/matrix-veles/graph/model"
|
||||||
|
"github.com/Unkn0wnCat/matrix-veles/internal/db"
|
||||||
model2 "github.com/Unkn0wnCat/matrix-veles/internal/db/model"
|
model2 "github.com/Unkn0wnCat/matrix-veles/internal/db/model"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
@ -9,6 +12,54 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func GetUserFromContext(ctx context.Context) (*model2.DBUser, error) {
|
||||||
|
userID, err := GetUserIDFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := db.GetUserByID(*userID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("invalid session")
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserIDFromContext(ctx context.Context) (*primitive.ObjectID, error) {
|
||||||
|
claimsVal := ctx.Value("claims")
|
||||||
|
var claims model2.JwtClaims
|
||||||
|
if claimsVal != nil {
|
||||||
|
claims = claimsVal.(model2.JwtClaims)
|
||||||
|
if claims.Valid() == nil {
|
||||||
|
sub := claims.Subject
|
||||||
|
|
||||||
|
id, err := primitive.ObjectIDFromHex(sub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("no user")
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckOwnerConstraint(ctx context.Context, realOwnerIDHex string) error {
|
||||||
|
constraint, ok := ctx.Value("ownerConstraint").(string)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil // This means no ownerConstraint is set
|
||||||
|
}
|
||||||
|
|
||||||
|
if constraint != realOwnerIDHex {
|
||||||
|
return errors.New("owner constraint violation")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func buildStringFilter(filter *model.StringFilter) bson.M {
|
func buildStringFilter(filter *model.StringFilter) bson.M {
|
||||||
compiledFilter := bson.M{}
|
compiledFilter := bson.M{}
|
||||||
|
|
||||||
|
@ -354,9 +405,9 @@ func buildDBEntryFilter(first *int, after *string, filter *model.EntryFilter, so
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if filter.FileURL != nil {
|
/*if filter.FileURL != nil {
|
||||||
filterBsonW["file_url"] = buildStringFilter(filter.FileURL)
|
filterBsonW["file_url"] = buildStringFilter(filter.FileURL)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if filter.PartOf != nil {
|
if filter.PartOf != nil {
|
||||||
filterBsonW["part_of"], err = buildIDArrayFilter(filter.PartOf)
|
filterBsonW["part_of"], err = buildIDArrayFilter(filter.PartOf)
|
||||||
|
|
|
@ -23,7 +23,7 @@ func MakeEntry(dbEntry *model.DBEntry) *Entry {
|
||||||
Tags: dbEntry.Tags,
|
Tags: dbEntry.Tags,
|
||||||
PartOfIDs: dbEntry.PartOf,
|
PartOfIDs: dbEntry.PartOf,
|
||||||
HashValue: dbEntry.HashValue,
|
HashValue: dbEntry.HashValue,
|
||||||
FileURL: &dbEntry.FileURL,
|
//FileURL: &dbEntry.FileURL,
|
||||||
Timestamp: dbEntry.Timestamp,
|
Timestamp: dbEntry.Timestamp,
|
||||||
AddedByID: *dbEntry.AddedBy,
|
AddedByID: *dbEntry.AddedBy,
|
||||||
RawComments: dbEntry.Comments,
|
RawComments: dbEntry.Comments,
|
||||||
|
|
|
@ -9,6 +9,15 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AddMxid struct {
|
||||||
|
Mxid string `json:"mxid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddToList struct {
|
||||||
|
List string `json:"list"`
|
||||||
|
Entries []string `json:"entries"`
|
||||||
|
}
|
||||||
|
|
||||||
type CommentConnection struct {
|
type CommentConnection struct {
|
||||||
PageInfo *PageInfo `json:"pageInfo"`
|
PageInfo *PageInfo `json:"pageInfo"`
|
||||||
Edges []*CommentEdge `json:"edges"`
|
Edges []*CommentEdge `json:"edges"`
|
||||||
|
@ -19,6 +28,31 @@ type CommentEdge struct {
|
||||||
Cursor string `json:"cursor"`
|
Cursor string `json:"cursor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CommentEntry struct {
|
||||||
|
Entry string `json:"entry"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommentList struct {
|
||||||
|
List string `json:"list"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateEntry struct {
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
PartOf []string `json:"partOf"`
|
||||||
|
HashValue string `json:"hashValue"`
|
||||||
|
Comment *string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateList struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Comment *string `json:"comment"`
|
||||||
|
Maintainers []string `json:"maintainers"`
|
||||||
|
Entries []string `json:"entries"`
|
||||||
|
}
|
||||||
|
|
||||||
type EntryArrayFilter struct {
|
type EntryArrayFilter struct {
|
||||||
ContainsAll []*EntryFilter `json:"containsAll"`
|
ContainsAll []*EntryFilter `json:"containsAll"`
|
||||||
ContainsOne []*EntryFilter `json:"containsOne"`
|
ContainsOne []*EntryFilter `json:"containsOne"`
|
||||||
|
@ -40,7 +74,6 @@ type EntryFilter struct {
|
||||||
HashValue *StringFilter `json:"hashValue"`
|
HashValue *StringFilter `json:"hashValue"`
|
||||||
Tags *StringArrayFilter `json:"tags"`
|
Tags *StringArrayFilter `json:"tags"`
|
||||||
AddedBy *string `json:"addedBy"`
|
AddedBy *string `json:"addedBy"`
|
||||||
FileURL *StringFilter `json:"fileUrl"`
|
|
||||||
Timestamp *TimestampFilter `json:"timestamp"`
|
Timestamp *TimestampFilter `json:"timestamp"`
|
||||||
PartOf *IDArrayFilter `json:"partOf"`
|
PartOf *IDArrayFilter `json:"partOf"`
|
||||||
}
|
}
|
||||||
|
@ -104,6 +137,16 @@ type PageInfo struct {
|
||||||
EndCursor string `json:"endCursor"`
|
EndCursor string `json:"endCursor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Register struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
MxID string `json:"mxID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveMxid struct {
|
||||||
|
Mxid string `json:"mxid"`
|
||||||
|
}
|
||||||
|
|
||||||
type SortRule struct {
|
type SortRule struct {
|
||||||
Direction SortDirection `json:"direction"`
|
Direction SortDirection `json:"direction"`
|
||||||
}
|
}
|
||||||
|
@ -195,3 +238,46 @@ func (e *SortDirection) UnmarshalGQL(v interface{}) error {
|
||||||
func (e SortDirection) MarshalGQL(w io.Writer) {
|
func (e SortDirection) MarshalGQL(w io.Writer) {
|
||||||
fmt.Fprint(w, strconv.Quote(e.String()))
|
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserRole string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserRoleAdmin UserRole = "ADMIN"
|
||||||
|
UserRoleUser UserRole = "USER"
|
||||||
|
UserRoleUnauthenticated UserRole = "UNAUTHENTICATED"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AllUserRole = []UserRole{
|
||||||
|
UserRoleAdmin,
|
||||||
|
UserRoleUser,
|
||||||
|
UserRoleUnauthenticated,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UserRole) IsValid() bool {
|
||||||
|
switch e {
|
||||||
|
case UserRoleAdmin, UserRoleUser, UserRoleUnauthenticated:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UserRole) String() string {
|
||||||
|
return string(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UserRole) UnmarshalGQL(v interface{}) error {
|
||||||
|
str, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("enums must be strings")
|
||||||
|
}
|
||||||
|
|
||||||
|
*e = UserRole(str)
|
||||||
|
if !e.IsValid() {
|
||||||
|
return fmt.Errorf("%s is not a valid UserRole", str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e UserRole) MarshalGQL(w io.Writer) {
|
||||||
|
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,15 @@
|
||||||
scalar Time
|
scalar Time
|
||||||
|
|
||||||
directive @loggedIn on FIELD_DEFINITION
|
directive @loggedIn on FIELD_DEFINITION
|
||||||
|
directive @hasRole(role: UserRole!) on FIELD_DEFINITION
|
||||||
|
directive @owner on FIELD_DEFINITION
|
||||||
|
directive @maintainer on FIELD_DEFINITION
|
||||||
|
|
||||||
|
enum UserRole {
|
||||||
|
ADMIN
|
||||||
|
USER
|
||||||
|
UNAUTHENTICATED
|
||||||
|
}
|
||||||
|
|
||||||
enum SortDirection {
|
enum SortDirection {
|
||||||
ASC
|
ASC
|
||||||
|
@ -48,7 +57,6 @@ type Entry {
|
||||||
tags: [String!]
|
tags: [String!]
|
||||||
partOf(first: Int, after: String): ListConnection
|
partOf(first: Int, after: String): ListConnection
|
||||||
hashValue: String!
|
hashValue: String!
|
||||||
fileUrl: String
|
|
||||||
timestamp: Time!
|
timestamp: Time!
|
||||||
addedBy: User!
|
addedBy: User!
|
||||||
comments(first: Int, after: String): CommentConnection
|
comments(first: Int, after: String): CommentConnection
|
||||||
|
@ -68,6 +76,7 @@ type List {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
tags: [String!]
|
tags: [String!]
|
||||||
|
creator: User!
|
||||||
comments(first: Int, after: String): CommentConnection
|
comments(first: Int, after: String): CommentConnection
|
||||||
maintainers(first: Int, after: String): UserConnection!
|
maintainers(first: Int, after: String): UserConnection!
|
||||||
entries(first: Int, after: String): EntryConnection
|
entries(first: Int, after: String): EntryConnection
|
||||||
|
@ -172,7 +181,6 @@ input EntryFilter {
|
||||||
hashValue: StringFilter
|
hashValue: StringFilter
|
||||||
tags: StringArrayFilter
|
tags: StringArrayFilter
|
||||||
addedBy: ID
|
addedBy: ID
|
||||||
fileUrl: StringFilter
|
|
||||||
timestamp: TimestampFilter
|
timestamp: TimestampFilter
|
||||||
partOf: IDArrayFilter
|
partOf: IDArrayFilter
|
||||||
}
|
}
|
||||||
|
@ -198,6 +206,8 @@ type Query {
|
||||||
user(id: ID, username: String): User! @loggedIn
|
user(id: ID, username: String): User! @loggedIn
|
||||||
entry(id: ID, hashValue: String): Entry! @loggedIn
|
entry(id: ID, hashValue: String): Entry! @loggedIn
|
||||||
list(id: ID, name: String): List! @loggedIn
|
list(id: ID, name: String): List! @loggedIn
|
||||||
|
|
||||||
|
self: User! @loggedIn
|
||||||
}
|
}
|
||||||
|
|
||||||
input Login {
|
input Login {
|
||||||
|
@ -205,6 +215,63 @@ input Login {
|
||||||
password: String!
|
password: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input Register {
|
||||||
|
username: String!
|
||||||
|
password: String!
|
||||||
|
mxID: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input CreateEntry {
|
||||||
|
tags: [String!]
|
||||||
|
partOf: [ID!]
|
||||||
|
hashValue: String!
|
||||||
|
comment: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input CommentEntry {
|
||||||
|
entry: ID!
|
||||||
|
comment: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input CreateList {
|
||||||
|
name: String!
|
||||||
|
tags: [String!]
|
||||||
|
comment: String
|
||||||
|
maintainers: [ID!]
|
||||||
|
entries: [ID!]
|
||||||
|
}
|
||||||
|
|
||||||
|
input CommentList {
|
||||||
|
list: ID!
|
||||||
|
comment: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input AddToList {
|
||||||
|
list: ID!
|
||||||
|
entries: [ID!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
input AddMXID {
|
||||||
|
mxid: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
input RemoveMXID {
|
||||||
|
mxid: String!
|
||||||
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
login(input: Login!): String!
|
login(input: Login!): String!
|
||||||
|
register(input: Register!): String! @hasRole(role: UNAUTHENTICATED)
|
||||||
|
addMXID(input: AddMXID!): User! @loggedIn
|
||||||
|
removeMXID(input: RemoveMXID!): User! @loggedIn
|
||||||
|
|
||||||
|
createEntry(input: CreateEntry!): Entry! @loggedIn
|
||||||
|
commentEntry(input: CommentEntry!): Entry! @loggedIn
|
||||||
|
deleteEntry(input: ID!): Boolean! @loggedIn @hasRole(role: ADMIN)
|
||||||
|
|
||||||
|
createList(input: CreateList!): List! @loggedIn
|
||||||
|
commentList(input: CommentList!): List! @loggedIn
|
||||||
|
addToList(input: AddToList!): List! @loggedIn @maintainer
|
||||||
|
deleteList(input: ID!): Boolean! @loggedIn @owner
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,10 @@ func (r *entryResolver) Comments(ctx context.Context, obj *model.Entry, first *i
|
||||||
return ResolveComments(comments, first, after)
|
return ResolveComments(comments, first, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *listResolver) Creator(ctx context.Context, obj *model.List) (*model.User, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
func (r *listResolver) Comments(ctx context.Context, obj *model.List, first *int, after *string) (*model.CommentConnection, error) {
|
func (r *listResolver) Comments(ctx context.Context, obj *model.List, first *int, after *string) (*model.CommentConnection, error) {
|
||||||
comments := obj.RawComments
|
comments := obj.RawComments
|
||||||
|
|
||||||
|
@ -325,6 +329,46 @@ func (r *mutationResolver) Login(ctx context.Context, input model.Login) (string
|
||||||
return ss, nil
|
return ss, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) Register(ctx context.Context, input model.Register) (string, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) AddMxid(ctx context.Context, input model.AddMxid) (*model.User, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) RemoveMxid(ctx context.Context, input model.RemoveMxid) (*model.User, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) CreateEntry(ctx context.Context, input model.CreateEntry) (*model.Entry, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) CommentEntry(ctx context.Context, input model.CommentEntry) (*model.Entry, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) DeleteEntry(ctx context.Context, input string) (bool, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) CreateList(ctx context.Context, input model.CreateList) (*model.List, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) CommentList(ctx context.Context, input model.CommentList) (*model.List, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) AddToList(ctx context.Context, input model.AddToList) (*model.List, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) DeleteList(ctx context.Context, input string) (bool, error) {
|
||||||
|
panic(fmt.Errorf("not implemented"))
|
||||||
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Users(ctx context.Context, first *int, after *string, filter *model.UserFilter, sort *model.UserSort) (*model.UserConnection, error) {
|
func (r *queryResolver) Users(ctx context.Context, first *int, after *string, filter *model.UserFilter, sort *model.UserSort) (*model.UserConnection, error) {
|
||||||
dbFilter, dbSort, dbLimit, err := buildDBUserFilter(first, after, filter, sort)
|
dbFilter, dbSort, dbLimit, err := buildDBUserFilter(first, after, filter, sort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -652,6 +696,15 @@ func (r *queryResolver) List(ctx context.Context, id *string, name *string) (*mo
|
||||||
return nil, errors.New("not found")
|
return nil, errors.New("not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *queryResolver) Self(ctx context.Context) (*model.User, error) {
|
||||||
|
user, err := GetUserFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("invalid session")
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.MakeUser(user), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Comment returns generated.CommentResolver implementation.
|
// Comment returns generated.CommentResolver implementation.
|
||||||
func (r *Resolver) Comment() generated.CommentResolver { return &commentResolver{r} }
|
func (r *Resolver) Comment() generated.CommentResolver { return &commentResolver{r} }
|
||||||
|
|
||||||
|
@ -672,16 +725,3 @@ type entryResolver struct{ *Resolver }
|
||||||
type listResolver struct{ *Resolver }
|
type listResolver struct{ *Resolver }
|
||||||
type mutationResolver struct{ *Resolver }
|
type mutationResolver struct{ *Resolver }
|
||||||
type queryResolver struct{ *Resolver }
|
type queryResolver struct{ *Resolver }
|
||||||
|
|
||||||
// !!! WARNING !!!
|
|
||||||
// The code below was going to be deleted when updating resolvers. It has been copied here so you have
|
|
||||||
// one last chance to move it out of harms way if you want. There are two reasons this happens:
|
|
||||||
// - When renaming or deleting a resolver the old code will be put in here. You can safely delete
|
|
||||||
// it when you're done.
|
|
||||||
// - You have helper methods in this file. Move them out to keep these resolver files clean.
|
|
||||||
func (r *commentResolver) Timestamp(ctx context.Context, obj *model.Comment) (*time.Time, error) {
|
|
||||||
panic(fmt.Errorf("not implemented"))
|
|
||||||
}
|
|
||||||
func (r *entryResolver) Timestamp(ctx context.Context, obj *model.Entry) (*time.Time, error) {
|
|
||||||
panic(fmt.Errorf("not implemented"))
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ type DBEntry struct {
|
||||||
Tags []string `bson:"tags" json:"tags"` // Tags used for searching entries and ordering
|
Tags []string `bson:"tags" json:"tags"` // Tags used for searching entries and ordering
|
||||||
PartOf []*primitive.ObjectID `bson:"part_of" json:"part_of"` // PartOf specifies the lists this entry is part of
|
PartOf []*primitive.ObjectID `bson:"part_of" json:"part_of"` // PartOf specifies the lists this entry is part of
|
||||||
HashValue string `bson:"hash_value" json:"hash"` // HashValue is the SHA512-hash of the file
|
HashValue string `bson:"hash_value" json:"hash"` // HashValue is the SHA512-hash of the file
|
||||||
FileURL string `bson:"file_url" json:"file_url"` // FileURL may be set to a file link
|
//FileURL string `bson:"file_url" json:"file_url"` // FileURL may be set to a file link
|
||||||
Timestamp time.Time `bson:"timestamp" json:"timestamp"` // Timestamp of when this entry was added
|
Timestamp time.Time `bson:"timestamp" json:"timestamp"` // Timestamp of when this entry was added
|
||||||
AddedBy *primitive.ObjectID `bson:"added_by" json:"added_by"` // AddedBy is a reference to the user who added this
|
AddedBy *primitive.ObjectID `bson:"added_by" json:"added_by"` // AddedBy is a reference to the user who added this
|
||||||
Comments []*DBComment `bson:"comments" json:"comments"` // Comments regarding this entry
|
Comments []*DBComment `bson:"comments" json:"comments"` // Comments regarding this entry
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/99designs/gqlgen/graphql/playground"
|
"github.com/99designs/gqlgen/graphql/playground"
|
||||||
"github.com/Unkn0wnCat/matrix-veles/graph"
|
"github.com/Unkn0wnCat/matrix-veles/graph"
|
||||||
"github.com/Unkn0wnCat/matrix-veles/graph/generated"
|
"github.com/Unkn0wnCat/matrix-veles/graph/generated"
|
||||||
|
model2 "github.com/Unkn0wnCat/matrix-veles/graph/model"
|
||||||
"github.com/Unkn0wnCat/matrix-veles/internal/db/model"
|
"github.com/Unkn0wnCat/matrix-veles/internal/db/model"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
|
@ -49,7 +50,43 @@ func SetupAPI() chi.Router {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New("authentication required")
|
return nil, errors.New("authorization required")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Directives.HasRole = func(ctx context.Context, obj interface{}, next graphql.Resolver, role model2.UserRole) (res interface{}, err error) {
|
||||||
|
user, err := graph.GetUserFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
if role == model2.UserRoleUnauthenticated {
|
||||||
|
return next(ctx)
|
||||||
|
}
|
||||||
|
return nil, errors.New("authorization required")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch role {
|
||||||
|
case model2.UserRoleUser:
|
||||||
|
return next(ctx)
|
||||||
|
case model2.UserRoleAdmin:
|
||||||
|
if user.Admin != nil && *user.Admin {
|
||||||
|
return next(ctx)
|
||||||
|
}
|
||||||
|
case model2.UserRoleUnauthenticated:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return nil, errors.New("server error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Directives.Owner = func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) {
|
||||||
|
user, err := graph.GetUserFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("authorization required")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx2 := context.WithValue(ctx, "ownerConstraint", user.ID.Hex())
|
||||||
|
|
||||||
|
return next(ctx2)
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := handler.NewDefaultServer(generated.NewExecutableSchema(c))
|
srv := handler.NewDefaultServer(generated.NewExecutableSchema(c))
|
||||||
|
|
|
@ -86,7 +86,7 @@ func apiHandleBotEntriesPost(res http.ResponseWriter, req *http.Request) {
|
||||||
Tags: body.Tags,
|
Tags: body.Tags,
|
||||||
PartOf: body.PartOf,
|
PartOf: body.PartOf,
|
||||||
HashValue: body.Hash,
|
HashValue: body.Hash,
|
||||||
FileURL: body.FileURL,
|
//FileURL: body.FileURL,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
AddedBy: &userId,
|
AddedBy: &userId,
|
||||||
Comments: nil,
|
Comments: nil,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue