diff --git a/backend/cmd/api/internal/controller/users.go b/backend/cmd/api/internal/controller/users.go index 4cf500b..1ed4c53 100644 --- a/backend/cmd/api/internal/controller/users.go +++ b/backend/cmd/api/internal/controller/users.go @@ -28,10 +28,10 @@ func GetUser(ctx context.Context, userid graphql.ID) (*model.User, error) { return model.FindUserById(ctx, userid) } -func CreateUser(ctx context.Context, email, fullname, role string) (*model.User, error) { - currentUser := auth.UserFromContext(ctx) +func SaveUser(ctx context.Context, userid *graphql.ID, email, fullname, role string) (*model.User, error) { + authenticatedUser := auth.UserFromContext(ctx) - if !currentUser.IsAdmin() { + if !authenticatedUser.IsAdmin() { return nil, &ForbiddenError{} } @@ -43,8 +43,10 @@ func CreateUser(ctx context.Context, email, fullname, role string) (*model.User, return nil, err } + if userid != nil { + return model.UpdateUser(ctx, *userid, email, fullname, role) + } return model.NewUser(ctx, email, fullname, role) - } func SaveUserFismaSystems(ctx context.Context, userid string, fismasystemids []int32) (*model.User, error) { diff --git a/backend/cmd/api/internal/graph/graph.go b/backend/cmd/api/internal/graph/graph.go index fdfc087..89a359f 100644 --- a/backend/cmd/api/internal/graph/graph.go +++ b/backend/cmd/api/internal/graph/graph.go @@ -64,7 +64,7 @@ type User { } type Mutation { - createUser(email: String!, fullname: String!, role: String!): UserMutationResponse! + saveUser(userid: ID, email: String!, fullname: String!, role: String!): UserMutationResponse! saveFunctionScore(scoreid: ID, fismasystemid: Int!, functionid: Int!, score: Float!, notes: String): FunctionScoreMutationReponse! assignFismaSystems(userid: String!, fismasystemids: [Int!]!): UserMutationResponse! unassignFismaSystems(userid: String!, fismasystemids: [Int!]!): UserMutationResponse! diff --git a/backend/cmd/api/internal/graph/users.go b/backend/cmd/api/internal/graph/users.go index f04cb42..56a9f06 100644 --- a/backend/cmd/api/internal/graph/users.go +++ b/backend/cmd/api/internal/graph/users.go @@ -22,15 +22,21 @@ func (r *RootResolver) User(ctx context.Context, args struct{ Userid graphql.ID return controller.GetUser(ctx, args.Userid) } -func (r *RootResolver) CreateUser(ctx context.Context, args struct { +func (r *RootResolver) SaveUser(ctx context.Context, args struct { + Userid *graphql.ID Email string Fullname string Role string }) *UserMutationResponse { res := UserMutationResponse{} - user, err := controller.CreateUser(ctx, args.Email, args.Fullname, args.Role) - res.SetCreated().SetError(err) + user, err := controller.SaveUser(ctx, args.Userid, args.Email, args.Fullname, args.Role) res.User = user + if args.Userid == nil { + res.SetCreated() + } else { + res.SetOK() + } + res.SetError(err) return &res } diff --git a/backend/cmd/api/internal/model/users.go b/backend/cmd/api/internal/model/users.go index 9391c0c..d433e07 100644 --- a/backend/cmd/api/internal/model/users.go +++ b/backend/cmd/api/internal/model/users.go @@ -27,6 +27,16 @@ func NewUser(ctx context.Context, email, fullname, role string) (*User, error) { return FindUserByEmail(ctx, email) } +func UpdateUser(ctx context.Context, userid graphql.ID, email, fullname, role string) (*User, error) { + sql := "UPDATE public.users SET email=$2, fullname=$3, role=$4 WHERE userid=$1" + _, err := exec(ctx, sql, userid, email, fullname, role) + if err != nil { + return nil, err + } + + return FindUserById(ctx, userid) +} + func (u *User) IsAdmin() bool { return u.Role == "ADMIN" } @@ -60,25 +70,19 @@ func FindUsers(ctx context.Context) ([]*User, error) { // FindUserByIf queries the database for a User with the given ID and returns *User or error func FindUserById(ctx context.Context, userid graphql.ID) (*User, error) { - sql := `SELECT users.userid, email, fullname, role, ARRAY_AGG(fismasystemid) AS fismasystems FROM users -LEFT JOIN users_fismasystems on users_fismasystems.userid = users.userid -WHERE users.userid=$1 -GROUP BY users.userid -` - return findUser(ctx, sql, []any{userid}) + return findUser(ctx, "users.userid=$1", []any{userid}) } // FindUserByEmail queries the database for a User with the given email address and returns *User or error func FindUserByEmail(ctx context.Context, email string) (*User, error) { + return findUser(ctx, "users.email=$1", []any{email}) +} + +func findUser(ctx context.Context, where string, args []any) (*User, error) { sql := `SELECT users.userid, email, fullname, role, ARRAY_AGG(fismasystemid) AS fismasystems FROM users LEFT JOIN users_fismasystems on users_fismasystems.userid = users.userid -WHERE users.email=$1 -GROUP BY users.userid +WHERE ` + where + ` GROUP BY users.userid ` - return findUser(ctx, sql, []any{email}) -} - -func findUser(ctx context.Context, sql string, args []any) (*User, error) { row, err := queryRow(ctx, sql, args...) if err != nil { return nil, err