fix: member permissions now works correctly

This commit is contained in:
Jordan Knott
2020-09-19 17:26:02 -05:00
parent 0366b4c7f7
commit 0d4fb6a0d0
29 changed files with 604 additions and 462 deletions

View File

@ -2,9 +2,10 @@ package commands
import (
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"time"
"github.com/RichardKnop/machinery/v1"
"github.com/RichardKnop/machinery/v1/config"

View File

@ -64,6 +64,9 @@ type Querier interface {
GetNotificationForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetNotificationForNotificationIDRow, error)
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskGroup(ctx context.Context, taskGroupID uuid.UUID) (uuid.UUID, error)
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)

View File

@ -25,4 +25,3 @@ WHERE n.notification_id = $1;
-- name: CreateNotification :one
INSERT INTO notification(notification_object_id, notifier_id)
VALUES ($1, $2) RETURNING *;

View File

@ -41,3 +41,16 @@ UPDATE task_checklist SET position = $2 WHERE task_checklist_id = $1 RETURNING *
-- name: UpdateTaskChecklistItemLocation :one
UPDATE task_checklist_item SET position = $2, task_checklist_id = $3 WHERE task_checklist_item_id = $1 RETURNING *;
-- name: GetProjectIDForTaskChecklist :one
SELECT project_id FROM task_checklist
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE task_checklist.task_checklist_id = $1;
-- name: GetProjectIDForTaskChecklistItem :one
SELECT project_id FROM task_checklist_item AS tci
INNER JOIN task_checklist ON task_checklist.task_checklist_id = tci.task_checklist_id
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE tci.task_checklist_item_id = $1;

View File

@ -5,6 +5,9 @@ INSERT INTO task_group (project_id, created_at, name, position)
-- name: GetTaskGroupsForProject :many
SELECT * FROM task_group WHERE project_id = $1;
-- name: GetProjectIDForTaskGroup :one
SELECT project_id from task_group WHERE task_group_id = $1;
-- name: GetAllTaskGroups :many
SELECT * FROM task_group;

View File

@ -90,6 +90,35 @@ func (q *Queries) DeleteTaskChecklistItem(ctx context.Context, taskChecklistItem
return err
}
const getProjectIDForTaskChecklist = `-- name: GetProjectIDForTaskChecklist :one
SELECT project_id FROM task_checklist
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE task_checklist.task_checklist_id = $1
`
func (q *Queries) GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskChecklist, taskChecklistID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getProjectIDForTaskChecklistItem = `-- name: GetProjectIDForTaskChecklistItem :one
SELECT project_id FROM task_checklist_item AS tci
INNER JOIN task_checklist ON task_checklist.task_checklist_id = tci.task_checklist_id
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE tci.task_checklist_item_id = $1
`
func (q *Queries) GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskChecklistItem, taskChecklistItemID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getTaskChecklistByID = `-- name: GetTaskChecklistByID :one
SELECT task_checklist_id, task_id, created_at, name, position FROM task_checklist WHERE task_checklist_id = $1
`

View File

@ -85,6 +85,17 @@ func (q *Queries) GetAllTaskGroups(ctx context.Context) ([]TaskGroup, error) {
return items, nil
}
const getProjectIDForTaskGroup = `-- name: GetProjectIDForTaskGroup :one
SELECT project_id from task_group WHERE task_group_id = $1
`
func (q *Queries) GetProjectIDForTaskGroup(ctx context.Context, taskGroupID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskGroup, taskGroupID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getTaskGroupByID = `-- name: GetTaskGroupByID :one
SELECT task_group_id, project_id, created_at, name, position FROM task_group WHERE task_group_id = $1
`

File diff suppressed because it is too large Load Diff

View File

@ -51,31 +51,56 @@ func NewHandler(repo db.Repository) http.Handler {
fieldName = "TeamID"
case ObjectTypeTask:
fieldName = "TaskID"
case ObjectTypeTaskGroup:
fieldName = "TaskGroupID"
case ObjectTypeTaskChecklist:
fieldName = "TaskChecklistID"
case ObjectTypeTaskChecklistItem:
fieldName = "TaskChecklistItemID"
default:
fieldName = "ProjectID"
}
log.WithFields(log.Fields{"typeArg": typeArg, "fieldName": fieldName}).Info("getting field by name")
subjectID, ok = val.FieldByName(fieldName).Interface().(uuid.UUID)
subjectField := val.FieldByName(fieldName)
if !subjectField.IsValid() {
log.Error("subject field name does not exist on input type")
return nil, errors.New("subject field name does not exist on input type")
}
subjectID, ok = subjectField.Interface().(uuid.UUID)
if !ok {
log.Error("error while casting subject UUID")
return nil, errors.New("error while casting subject uuid")
}
var err error
if level == ActionLevelProject {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching subject ID by typeArg")
if typeArg == ObjectTypeTask {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching project ID using task ID")
subjectID, err = repo.GetProjectIDForTask(ctx, subjectID)
if err != nil {
return nil, err
}
}
roles, err := GetProjectRoles(ctx, repo, subjectID)
if typeArg == ObjectTypeTaskGroup {
subjectID, err = repo.GetProjectIDForTaskGroup(ctx, subjectID)
}
if typeArg == ObjectTypeTaskChecklist {
subjectID, err = repo.GetProjectIDForTaskChecklist(ctx, subjectID)
}
if typeArg == ObjectTypeTaskChecklistItem {
subjectID, err = repo.GetProjectIDForTaskChecklistItem(ctx, subjectID)
}
if err != nil {
log.WithError(err).Error("error while getting subject ID")
return nil, err
}
if roles.TeamRole == "admin" || roles.ProjectRole == "admin" {
log.WithFields(log.Fields{"teamRole": roles.TeamRole, "projectRole": roles.ProjectRole}).Info("is team or project role")
return next(ctx)
projectRoles, err := GetProjectRoles(ctx, repo, subjectID)
if err != nil {
log.WithError(err).Error("error while getting project roles")
return nil, err
}
for _, validRole := range roles {
if GetRoleLevel(projectRoles.TeamRole) == validRole || GetRoleLevel(projectRoles.ProjectRole) == validRole {
log.WithFields(log.Fields{"teamRole": projectRoles.TeamRole, "projectRole": projectRoles.ProjectRole}).Info("is team or project role")
return next(ctx)
}
}
return nil, errors.New("must be a team or project admin")
} else if level == ActionLevelTeam {
@ -85,10 +110,13 @@ func NewHandler(repo db.Repository) http.Handler {
}
role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID})
if err != nil {
log.WithError(err).Error("error while getting team roles for user ID")
return nil, err
}
if role.RoleCode == "admin" {
return next(ctx)
for _, validRole := range roles {
if GetRoleLevel(role.RoleCode) == validRole || GetRoleLevel(role.RoleCode) == validRole {
return next(ctx)
}
}
return nil, errors.New("must be a team admin")
@ -156,6 +184,14 @@ func GetProjectRoles(ctx context.Context, r db.Repository, projectID uuid.UUID)
return r.GetUserRolesForProject(ctx, db.GetUserRolesForProjectParams{UserID: userID, ProjectID: projectID})
}
// GetRoleLevel converts a role level string to a RoleLevel type
func GetRoleLevel(r string) RoleLevel {
if r == RoleLevelAdmin.String() {
return RoleLevelAdmin
}
return RoleLevelMember
}
// ConvertToRoleCode converts a role code string to a RoleCode type
func ConvertToRoleCode(r string) RoleCode {
if r == RoleCodeAdmin.String() {

View File

@ -121,11 +121,11 @@ type DeleteTaskGroupTasksPayload struct {
}
type DeleteTaskInput struct {
TaskID string `json:"taskID"`
TaskID uuid.UUID `json:"taskID"`
}
type DeleteTaskPayload struct {
TaskID string `json:"taskID"`
TaskID uuid.UUID `json:"taskID"`
}
type DeleteTeam struct {
@ -184,11 +184,11 @@ type FindTeam struct {
}
type FindUser struct {
UserID string `json:"userId"`
UserID uuid.UUID `json:"userID"`
}
type LogoutUser struct {
UserID string `json:"userID"`
UserID uuid.UUID `json:"userID"`
}
type MePayload struct {
@ -225,19 +225,19 @@ type NewProjectLabel struct {
}
type NewRefreshToken struct {
UserID string `json:"userId"`
UserID uuid.UUID `json:"userID"`
}
type NewTask struct {
TaskGroupID string `json:"taskGroupID"`
Name string `json:"name"`
Position float64 `json:"position"`
TaskGroupID uuid.UUID `json:"taskGroupID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type NewTaskGroup struct {
ProjectID string `json:"projectID"`
Name string `json:"name"`
Position float64 `json:"position"`
ProjectID uuid.UUID `json:"projectID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type NewTaskGroupLocation struct {
@ -303,6 +303,7 @@ type ProjectsFilter struct {
}
type RemoveTaskLabelInput struct {
TaskID uuid.UUID `json:"taskID"`
TaskLabelID uuid.UUID `json:"taskLabelID"`
}
@ -388,13 +389,13 @@ type UpdateProjectName struct {
}
type UpdateTaskChecklistItemLocation struct {
ChecklistID uuid.UUID `json:"checklistID"`
ChecklistItemID uuid.UUID `json:"checklistItemID"`
Position float64 `json:"position"`
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Position float64 `json:"position"`
}
type UpdateTaskChecklistItemLocationPayload struct {
ChecklistID uuid.UUID `json:"checklistID"`
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
PrevChecklistID uuid.UUID `json:"prevChecklistID"`
ChecklistItem *db.TaskChecklistItem `json:"checklistItem"`
}
@ -405,8 +406,8 @@ type UpdateTaskChecklistItemName struct {
}
type UpdateTaskChecklistLocation struct {
ChecklistID uuid.UUID `json:"checklistID"`
Position float64 `json:"position"`
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Position float64 `json:"position"`
}
type UpdateTaskChecklistLocationPayload struct {
@ -439,8 +440,8 @@ type UpdateTaskLocationPayload struct {
}
type UpdateTaskName struct {
TaskID string `json:"taskID"`
Name string `json:"name"`
TaskID uuid.UUID `json:"taskID"`
Name string `json:"name"`
}
type UpdateTeamMemberRole struct {
@ -648,10 +649,13 @@ func (e EntityType) MarshalGQL(w io.Writer) {
type ObjectType string
const (
ObjectTypeOrg ObjectType = "ORG"
ObjectTypeTeam ObjectType = "TEAM"
ObjectTypeProject ObjectType = "PROJECT"
ObjectTypeTask ObjectType = "TASK"
ObjectTypeOrg ObjectType = "ORG"
ObjectTypeTeam ObjectType = "TEAM"
ObjectTypeProject ObjectType = "PROJECT"
ObjectTypeTask ObjectType = "TASK"
ObjectTypeTaskGroup ObjectType = "TASK_GROUP"
ObjectTypeTaskChecklist ObjectType = "TASK_CHECKLIST"
ObjectTypeTaskChecklistItem ObjectType = "TASK_CHECKLIST_ITEM"
)
var AllObjectType = []ObjectType{
@ -659,11 +663,14 @@ var AllObjectType = []ObjectType{
ObjectTypeTeam,
ObjectTypeProject,
ObjectTypeTask,
ObjectTypeTaskGroup,
ObjectTypeTaskChecklist,
ObjectTypeTaskChecklistItem,
}
func (e ObjectType) IsValid() bool {
switch e {
case ObjectTypeOrg, ObjectTypeTeam, ObjectTypeProject, ObjectTypeTask:
case ObjectTypeOrg, ObjectTypeTeam, ObjectTypeProject, ObjectTypeTask, ObjectTypeTaskGroup, ObjectTypeTaskChecklist, ObjectTypeTaskChecklistItem:
return true
}
return false

View File

@ -174,6 +174,9 @@ enum ObjectType {
TEAM
PROJECT
TASK
TASK_GROUP
TASK_CHECKLIST
TASK_CHECKLIST_ITEM
}
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
@ -215,7 +218,7 @@ input ProjectsFilter {
}
input FindUser {
userId: String!
userID: UUID!
}
input FindProject {
@ -297,15 +300,15 @@ type DeleteProjectPayload {
extend type Mutation {
createProjectLabel(input: NewProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
deleteProjectLabel(input: DeleteProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabel(input: UpdateProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelName(input: UpdateProjectLabelName!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelColor(input: UpdateProjectLabelColor!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
}
input NewProjectLabel {
@ -377,29 +380,29 @@ type UpdateProjectMemberRolePayload {
extend type Mutation {
createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTask(input: DeleteTaskInput!):
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDescription(input: UpdateTaskDescriptionInput!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskLocation(input: NewTaskLocation!):
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskName(input: UpdateTaskName!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
setTaskComplete(input: SetTaskComplete!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDueDate(input: UpdateTaskDueDate!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
assignTask(input: AssignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
unassignTask(input: UnassignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input NewTask {
taskGroupID: String!
taskGroupID: UUID!
name: String!
position: Float!
}
@ -441,54 +444,55 @@ input NewTaskLocation {
}
input DeleteTaskInput {
taskID: String!
taskID: UUID!
}
type DeleteTaskPayload {
taskID: String!
taskID: UUID!
}
input UpdateTaskName {
taskID: String!
taskID: UUID!
name: String!
}
extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
deleteTaskChecklist(input: DeleteTaskChecklist!):
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistName(input: UpdateTaskChecklistName!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
createTaskChecklistItem(input: CreateTaskChecklistItem!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
}
input UpdateTaskChecklistItemLocation {
checklistID: UUID!
checklistItemID: UUID!
taskChecklistID: UUID!
taskChecklistItemID: UUID!
position: Float!
}
type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID!
taskChecklistID: UUID!
prevChecklistID: UUID!
checklistItem: TaskChecklistItem!
}
input UpdateTaskChecklistLocation {
checklistID: UUID!
taskChecklistID: UUID!
position: Float!
}
@ -541,19 +545,19 @@ type DeleteTaskChecklistPayload {
extend type Mutation {
createTaskGroup(input: NewTaskGroup!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateTaskGroupLocation(input: NewTaskGroupLocation!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
updateTaskGroupName(input: UpdateTaskGroupName!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroup(input: DeleteTaskGroupInput!):
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
duplicateTaskGroup(input: DuplicateTaskGroup!):
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
sortTaskGroup(input: SortTaskGroup!):
SortTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroupTasks(input: DeleteTaskGroupTasks!):
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
}
input DeleteTaskGroupTasks {
@ -612,19 +616,31 @@ type DeleteTaskGroupPayload {
}
input NewTaskGroup {
projectID: String!
projectID: UUID!
name: String!
position: Float!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskID: UUID!
taskLabelID: UUID!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
@ -634,15 +650,6 @@ type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
}
extend type Mutation {
deleteTeam(input: DeleteTeam!):
@ -758,7 +765,7 @@ type UpdateUserRolePayload {
}
input NewRefreshToken {
userId: String!
userID: UUID!
}
input NewUserAccount {
@ -771,7 +778,7 @@ input NewUserAccount {
}
input LogoutUser {
userID: String!
userID: UUID!
}
input DeleteUserAccount {

View File

@ -179,14 +179,9 @@ func (r *mutationResolver) UpdateProjectMemberRole(ctx context.Context, input Up
}
func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.Task, error) {
taskGroupID, err := uuid.Parse(input.TaskGroupID)
if err != nil {
log.WithError(err).Error("issue while parsing task group ID")
return &db.Task{}, err
}
createdAt := time.Now().UTC()
log.WithFields(log.Fields{"positon": input.Position, "taskGroupID": taskGroupID}).Info("creating task")
task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{taskGroupID, createdAt, input.Name, input.Position})
log.WithFields(log.Fields{"positon": input.Position, "taskGroupID": input.TaskGroupID}).Info("creating task")
task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{input.TaskGroupID, createdAt, input.Name, input.Position})
if err != nil {
log.WithError(err).Error("issue while creating task")
return &db.Task{}, err
@ -195,19 +190,14 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.T
}
func (r *mutationResolver) DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error) {
taskID, err := uuid.Parse(input.TaskID)
if err != nil {
return &DeleteTaskPayload{}, err
}
log.WithFields(log.Fields{
"taskID": taskID.String(),
"taskID": input.TaskID,
}).Info("deleting task")
err = r.Repository.DeleteTaskByID(ctx, taskID)
err := r.Repository.DeleteTaskByID(ctx, input.TaskID)
if err != nil {
return &DeleteTaskPayload{}, err
}
return &DeleteTaskPayload{taskID.String()}, nil
return &DeleteTaskPayload{input.TaskID}, nil
}
func (r *mutationResolver) UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*db.Task, error) {
@ -226,11 +216,7 @@ func (r *mutationResolver) UpdateTaskLocation(ctx context.Context, input NewTask
}
func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskName) (*db.Task, error) {
taskID, err := uuid.Parse(input.TaskID)
if err != nil {
return &db.Task{}, err
}
task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{taskID, input.Name})
task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{input.TaskID, input.Name})
return &task, err
}
@ -336,6 +322,16 @@ func (r *mutationResolver) CreateTaskChecklistItem(ctx context.Context, input Cr
return &taskChecklistItem, nil
}
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.TaskChecklistID})
if err != nil {
return &UpdateTaskChecklistLocationPayload{}, err
}
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemName(ctx context.Context, input UpdateTaskChecklistItemName) (*db.TaskChecklistItem, error) {
task, err := r.Repository.UpdateTaskChecklistItemName(ctx, db.UpdateTaskChecklistItemNameParams{TaskChecklistItemID: input.TaskChecklistItemID,
Name: input.Name,
@ -375,34 +371,20 @@ func (r *mutationResolver) DeleteTaskChecklistItem(ctx context.Context, input De
}, err
}
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.ChecklistID})
if err != nil {
return &UpdateTaskChecklistLocationPayload{}, err
}
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemLocation(ctx context.Context, input UpdateTaskChecklistItemLocation) (*UpdateTaskChecklistItemLocationPayload, error) {
currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.ChecklistItemID)
currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.TaskChecklistItemID)
checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.ChecklistID, TaskChecklistItemID: input.ChecklistItemID, Position: input.Position})
checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.TaskChecklistID, TaskChecklistItemID: input.TaskChecklistItemID, Position: input.Position})
if err != nil {
return &UpdateTaskChecklistItemLocationPayload{}, err
}
return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, ChecklistID: input.ChecklistID, ChecklistItem: &checklistItem}, err
return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, TaskChecklistID: input.TaskChecklistID, ChecklistItem: &checklistItem}, err
}
func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*db.TaskGroup, error) {
createdAt := time.Now().UTC()
projectID, err := uuid.Parse(input.ProjectID)
if err != nil {
return &db.TaskGroup{}, err
}
project, err := r.Repository.CreateTaskGroup(ctx,
db.CreateTaskGroupParams{projectID, createdAt, input.Name, input.Position})
db.CreateTaskGroupParams{input.ProjectID, createdAt, input.Name, input.Position})
return &project, err
}
@ -773,12 +755,7 @@ func (r *mutationResolver) DeleteUserAccount(ctx context.Context, input DeleteUs
}
func (r *mutationResolver) LogoutUser(ctx context.Context, input LogoutUser) (bool, error) {
userID, err := uuid.Parse(input.UserID)
if err != nil {
return false, err
}
err = r.Repository.DeleteRefreshTokenByUserID(ctx, userID)
err := r.Repository.DeleteRefreshTokenByUserID(ctx, input.UserID)
return true, err
}
@ -978,11 +955,7 @@ func (r *queryResolver) Users(ctx context.Context) ([]db.UserAccount, error) {
}
func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error) {
userID, err := uuid.Parse(input.UserID)
if err != nil {
return &db.UserAccount{}, err
}
account, err := r.Repository.GetUserAccountByID(ctx, userID)
account, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
if err == sql.ErrNoRows {
return &db.UserAccount{}, &gqlerror.Error{
Message: "User not found",

View File

@ -14,6 +14,9 @@ enum ObjectType {
TEAM
PROJECT
TASK
TASK_GROUP
TASK_CHECKLIST
TASK_CHECKLIST_ITEM
}
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
@ -55,7 +58,7 @@ input ProjectsFilter {
}
input FindUser {
userId: String!
userID: UUID!
}
input FindProject {

View File

@ -1,14 +1,14 @@
extend type Mutation {
createProjectLabel(input: NewProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
deleteProjectLabel(input: DeleteProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabel(input: UpdateProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelName(input: UpdateProjectLabelName!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelColor(input: UpdateProjectLabelColor!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
}
input NewProjectLabel {

View File

@ -1,28 +1,28 @@
extend type Mutation {
createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTask(input: DeleteTaskInput!):
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDescription(input: UpdateTaskDescriptionInput!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskLocation(input: NewTaskLocation!):
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskName(input: UpdateTaskName!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
setTaskComplete(input: SetTaskComplete!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDueDate(input: UpdateTaskDueDate!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
assignTask(input: AssignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
unassignTask(input: UnassignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input NewTask {
taskGroupID: String!
taskGroupID: UUID!
name: String!
position: Float!
}
@ -64,14 +64,14 @@ input NewTaskLocation {
}
input DeleteTaskInput {
taskID: String!
taskID: UUID!
}
type DeleteTaskPayload {
taskID: String!
taskID: UUID!
}
input UpdateTaskName {
taskID: String!
taskID: UUID!
name: String!
}

View File

@ -1,39 +1,40 @@
extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
deleteTaskChecklist(input: DeleteTaskChecklist!):
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistName(input: UpdateTaskChecklistName!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
createTaskChecklistItem(input: CreateTaskChecklistItem!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
}
input UpdateTaskChecklistItemLocation {
checklistID: UUID!
checklistItemID: UUID!
taskChecklistID: UUID!
taskChecklistItemID: UUID!
position: Float!
}
type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID!
taskChecklistID: UUID!
prevChecklistID: UUID!
checklistItem: TaskChecklistItem!
}
input UpdateTaskChecklistLocation {
checklistID: UUID!
taskChecklistID: UUID!
position: Float!
}

View File

@ -1,18 +1,18 @@
extend type Mutation {
createTaskGroup(input: NewTaskGroup!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateTaskGroupLocation(input: NewTaskGroupLocation!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
updateTaskGroupName(input: UpdateTaskGroupName!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroup(input: DeleteTaskGroupInput!):
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
duplicateTaskGroup(input: DuplicateTaskGroup!):
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
sortTaskGroup(input: SortTaskGroup!):
SortTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroupTasks(input: DeleteTaskGroupTasks!):
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
}
input DeleteTaskGroupTasks {
@ -71,7 +71,7 @@ type DeleteTaskGroupPayload {
}
input NewTaskGroup {
projectID: String!
projectID: UUID!
name: String!
position: Float!
}

View File

@ -1,11 +1,23 @@
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskID: UUID!
taskLabelID: UUID!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
@ -15,12 +27,3 @@ type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
}

View File

@ -46,7 +46,7 @@ type UpdateUserRolePayload {
}
input NewRefreshToken {
userId: String!
userID: UUID!
}
input NewUserAccount {
@ -59,7 +59,7 @@ input NewUserAccount {
}
input LogoutUser {
userID: String!
userID: UUID!
}
input DeleteUserAccount {