feat: projects can be set to public
This commit is contained in:
@ -53,10 +53,11 @@ type PersonalProject struct {
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
PublicOn sql.NullTime `json:"public_on"`
|
||||
}
|
||||
|
||||
type ProjectLabel struct {
|
||||
|
@ -5,13 +5,14 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createPersonalProject = `-- name: CreatePersonalProject :one
|
||||
INSERT INTO project(team_id, created_at, name) VALUES (null, $1, $2) RETURNING project_id, team_id, created_at, name
|
||||
INSERT INTO project(team_id, created_at, name) VALUES (null, $1, $2) RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type CreatePersonalProjectParams struct {
|
||||
@ -27,6 +28,7 @@ func (q *Queries) CreatePersonalProject(ctx context.Context, arg CreatePersonalP
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -78,7 +80,7 @@ func (q *Queries) CreateProjectMember(ctx context.Context, arg CreateProjectMemb
|
||||
}
|
||||
|
||||
const createTeamProject = `-- name: CreateTeamProject :one
|
||||
INSERT INTO project(team_id, created_at, name) VALUES ($1, $2, $3) RETURNING project_id, team_id, created_at, name
|
||||
INSERT INTO project(team_id, created_at, name) VALUES ($1, $2, $3) RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type CreateTeamProjectParams struct {
|
||||
@ -95,6 +97,7 @@ func (q *Queries) CreateTeamProject(ctx context.Context, arg CreateTeamProjectPa
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -132,7 +135,7 @@ func (q *Queries) DeleteProjectMember(ctx context.Context, arg DeleteProjectMemb
|
||||
}
|
||||
|
||||
const getAllProjectsForTeam = `-- name: GetAllProjectsForTeam :many
|
||||
SELECT project_id, team_id, created_at, name FROM project WHERE team_id = $1
|
||||
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error) {
|
||||
@ -149,6 +152,7 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -164,7 +168,7 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
|
||||
}
|
||||
|
||||
const getAllTeamProjects = `-- name: GetAllTeamProjects :many
|
||||
SELECT project_id, team_id, created_at, name FROM project WHERE team_id IS NOT null
|
||||
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE team_id IS NOT null
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
|
||||
@ -181,6 +185,7 @@ func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -196,7 +201,7 @@ func (q *Queries) GetAllTeamProjects(ctx context.Context) ([]Project, error) {
|
||||
}
|
||||
|
||||
const getAllVisibleProjectsForUserID = `-- name: GetAllVisibleProjectsForUserID :many
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name FROM project LEFT JOIN
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on FROM project LEFT JOIN
|
||||
project_member ON project_member.project_id = project.project_id WHERE project_member.user_id = $1
|
||||
`
|
||||
|
||||
@ -214,6 +219,7 @@ func (q *Queries) GetAllVisibleProjectsForUserID(ctx context.Context, userID uui
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -292,7 +298,7 @@ func (q *Queries) GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.
|
||||
}
|
||||
|
||||
const getPersonalProjectsForUserID = `-- name: GetPersonalProjectsForUserID :many
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name FROM project
|
||||
SELECT project.project_id, project.team_id, project.created_at, project.name, project.public_on FROM project
|
||||
LEFT JOIN personal_project ON personal_project.project_id = project.project_id
|
||||
WHERE personal_project.user_id = $1
|
||||
`
|
||||
@ -311,6 +317,7 @@ func (q *Queries) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -326,7 +333,7 @@ func (q *Queries) GetPersonalProjectsForUserID(ctx context.Context, userID uuid.
|
||||
}
|
||||
|
||||
const getProjectByID = `-- name: GetProjectByID :one
|
||||
SELECT project_id, team_id, created_at, name FROM project WHERE project_id = $1
|
||||
SELECT project_id, team_id, created_at, name, public_on FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) {
|
||||
@ -337,6 +344,7 @@ func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Proj
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -426,6 +434,17 @@ func (q *Queries) GetProjectRolesForUserID(ctx context.Context, userID uuid.UUID
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getPublicOn = `-- name: GetPublicOn :one
|
||||
SELECT public_on FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetPublicOn(ctx context.Context, projectID uuid.UUID) (sql.NullTime, error) {
|
||||
row := q.db.QueryRowContext(ctx, getPublicOn, projectID)
|
||||
var public_on sql.NullTime
|
||||
err := row.Scan(&public_on)
|
||||
return public_on, err
|
||||
}
|
||||
|
||||
const getRoleForProjectMemberByUserID = `-- name: GetRoleForProjectMemberByUserID :one
|
||||
SELECT code, role.name FROM project_member INNER JOIN role ON role.code = project_member.role_code
|
||||
WHERE user_id = $1 AND project_id = $2
|
||||
@ -469,6 +488,28 @@ func (q *Queries) GetUserRolesForProject(ctx context.Context, arg GetUserRolesFo
|
||||
return i, err
|
||||
}
|
||||
|
||||
const setPublicOn = `-- name: SetPublicOn :one
|
||||
UPDATE project SET public_on = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type SetPublicOnParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
PublicOn sql.NullTime `json:"public_on"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, setPublicOn, arg.ProjectID, arg.PublicOn)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateProjectMemberRole = `-- name: UpdateProjectMemberRole :one
|
||||
UPDATE project_member SET role_code = $3 WHERE project_id = $1 AND user_id = $2
|
||||
RETURNING project_member_id, project_id, user_id, added_at, role_code
|
||||
@ -494,7 +535,7 @@ func (q *Queries) UpdateProjectMemberRole(ctx context.Context, arg UpdateProject
|
||||
}
|
||||
|
||||
const updateProjectNameByID = `-- name: UpdateProjectNameByID :one
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, public_on
|
||||
`
|
||||
|
||||
type UpdateProjectNameByIDParams struct {
|
||||
@ -510,6 +551,7 @@ func (q *Queries) UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNa
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.PublicOn,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@ -100,6 +101,7 @@ type Querier interface {
|
||||
GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)
|
||||
GetProjectRolesForUserID(ctx context.Context, userID uuid.UUID) ([]GetProjectRolesForUserIDRow, error)
|
||||
GetProjectsForInvitedMember(ctx context.Context, email string) ([]uuid.UUID, error)
|
||||
GetPublicOn(ctx context.Context, projectID uuid.UUID) (sql.NullTime, error)
|
||||
GetRecentlyAssignedTaskForUserID(ctx context.Context, arg GetRecentlyAssignedTaskForUserIDParams) ([]Task, error)
|
||||
GetRoleForProjectMemberByUserID(ctx context.Context, arg GetRoleForProjectMemberByUserIDParams) (Role, error)
|
||||
GetRoleForTeamMember(ctx context.Context, arg GetRoleForTeamMemberParams) (Role, error)
|
||||
@ -132,6 +134,7 @@ type Querier interface {
|
||||
HasAnyUser(ctx context.Context) (bool, error)
|
||||
SetFirstUserActive(ctx context.Context) (UserAccount, error)
|
||||
SetInactiveLastMoveForTaskID(ctx context.Context, taskID uuid.UUID) error
|
||||
SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Project, error)
|
||||
SetTaskChecklistItemComplete(ctx context.Context, arg SetTaskChecklistItemCompleteParams) (TaskChecklistItem, error)
|
||||
SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams) (Task, error)
|
||||
SetTaskGroupName(ctx context.Context, arg SetTaskGroupNameParams) (TaskGroup, error)
|
||||
|
@ -77,3 +77,9 @@ SELECT p.team_id, COALESCE(tm.role_code, '') AS team_role, COALESCE(pm.role_code
|
||||
|
||||
-- name: CreatePersonalProjectLink :one
|
||||
INSERT INTO personal_project (project_id, user_id) VALUES ($1, $2) RETURNING *;
|
||||
|
||||
-- name: SetPublicOn :one
|
||||
UPDATE project SET public_on = $2 WHERE project_id = $1 RETURNING *;
|
||||
|
||||
-- name: GetPublicOn :one
|
||||
SELECT public_on FROM project WHERE project_id = $1;
|
||||
|
@ -57,7 +57,8 @@ type ResolverRoot interface {
|
||||
}
|
||||
|
||||
type DirectiveRoot struct {
|
||||
HasRole func(ctx context.Context, obj interface{}, next graphql.Resolver, roles []RoleLevel, level ActionLevel, typeArg ObjectType) (res interface{}, err error)
|
||||
HasRole func(ctx context.Context, obj interface{}, next graphql.Resolver, roles []RoleLevel, level ActionLevel, typeArg ObjectType) (res interface{}, err error)
|
||||
RequiresUser func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error)
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
@ -248,6 +249,7 @@ type ComplexityRoot struct {
|
||||
SetTaskChecklistItemComplete func(childComplexity int, input SetTaskChecklistItemComplete) int
|
||||
SetTaskComplete func(childComplexity int, input SetTaskComplete) int
|
||||
SortTaskGroup func(childComplexity int, input SortTaskGroup) int
|
||||
ToggleProjectVisibility func(childComplexity int, input ToggleProjectVisibility) int
|
||||
ToggleTaskLabel func(childComplexity int, input ToggleTaskLabelInput) int
|
||||
UnassignTask func(childComplexity int, input *UnassignTaskInput) int
|
||||
UpdateProjectLabel func(childComplexity int, input UpdateProjectLabel) int
|
||||
@ -327,6 +329,7 @@ type ComplexityRoot struct {
|
||||
Members func(childComplexity int) int
|
||||
Name func(childComplexity int) int
|
||||
Permission func(childComplexity int) int
|
||||
PublicOn func(childComplexity int) int
|
||||
TaskGroups func(childComplexity int) int
|
||||
Team func(childComplexity int) int
|
||||
}
|
||||
@ -476,6 +479,10 @@ type ComplexityRoot struct {
|
||||
TeamID func(childComplexity int) int
|
||||
}
|
||||
|
||||
ToggleProjectVisibilityPayload struct {
|
||||
Project func(childComplexity int) int
|
||||
}
|
||||
|
||||
ToggleTaskLabelPayload struct {
|
||||
Active func(childComplexity int) int
|
||||
Task func(childComplexity int) int
|
||||
@ -547,6 +554,7 @@ type MutationResolver interface {
|
||||
CreateProject(ctx context.Context, input NewProject) (*db.Project, error)
|
||||
DeleteProject(ctx context.Context, input DeleteProject) (*DeleteProjectPayload, error)
|
||||
UpdateProjectName(ctx context.Context, input *UpdateProjectName) (*db.Project, error)
|
||||
ToggleProjectVisibility(ctx context.Context, input ToggleProjectVisibility) (*ToggleProjectVisibilityPayload, error)
|
||||
CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*db.ProjectLabel, error)
|
||||
DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*db.ProjectLabel, error)
|
||||
UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*db.ProjectLabel, error)
|
||||
@ -619,6 +627,7 @@ type ProjectResolver interface {
|
||||
TaskGroups(ctx context.Context, obj *db.Project) ([]db.TaskGroup, error)
|
||||
Members(ctx context.Context, obj *db.Project) ([]Member, error)
|
||||
InvitedMembers(ctx context.Context, obj *db.Project) ([]InvitedMember, error)
|
||||
PublicOn(ctx context.Context, obj *db.Project) (*time.Time, error)
|
||||
Permission(ctx context.Context, obj *db.Project) (*ProjectPermission, error)
|
||||
Labels(ctx context.Context, obj *db.Project) ([]db.ProjectLabel, error)
|
||||
}
|
||||
@ -1624,6 +1633,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Mutation.SortTaskGroup(childComplexity, args["input"].(SortTaskGroup)), true
|
||||
|
||||
case "Mutation.toggleProjectVisibility":
|
||||
if e.complexity.Mutation.ToggleProjectVisibility == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Mutation_toggleProjectVisibility_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.ToggleProjectVisibility(childComplexity, args["input"].(ToggleProjectVisibility)), true
|
||||
|
||||
case "Mutation.toggleTaskLabel":
|
||||
if e.complexity.Mutation.ToggleTaskLabel == nil {
|
||||
break
|
||||
@ -2098,6 +2119,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Project.Permission(childComplexity), true
|
||||
|
||||
case "Project.publicOn":
|
||||
if e.complexity.Project.PublicOn == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Project.PublicOn(childComplexity), true
|
||||
|
||||
case "Project.taskGroups":
|
||||
if e.complexity.Project.TaskGroups == nil {
|
||||
break
|
||||
@ -2763,6 +2791,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.TeamRole.TeamID(childComplexity), true
|
||||
|
||||
case "ToggleProjectVisibilityPayload.project":
|
||||
if e.complexity.ToggleProjectVisibilityPayload.Project == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.ToggleProjectVisibilityPayload.Project(childComplexity), true
|
||||
|
||||
case "ToggleTaskLabelPayload.active":
|
||||
if e.complexity.ToggleTaskLabelPayload.Active == nil {
|
||||
break
|
||||
@ -3158,6 +3193,7 @@ type Project {
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
invitedMembers: [InvitedMember!]!
|
||||
publicOn: Time
|
||||
permission: ProjectPermission!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
@ -3294,6 +3330,7 @@ enum ObjectType {
|
||||
}
|
||||
|
||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
|
||||
directive @requiresUser on FIELD_DEFINITION
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
@ -3301,7 +3338,7 @@ type Query {
|
||||
invitedUsers: [InvitedUserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!):
|
||||
Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
|
||||
Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
@ -3309,7 +3346,7 @@ type Query {
|
||||
myTasks(input: MyTasks!): MyTasksPayload!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: MePayload!
|
||||
me: MePayload
|
||||
}
|
||||
|
||||
|
||||
@ -3427,6 +3464,16 @@ extend type Mutation {
|
||||
DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateProjectName(input: UpdateProjectName):
|
||||
Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleProjectVisibility(input: ToggleProjectVisibility!): ToggleProjectVisibilityPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input ToggleProjectVisibility {
|
||||
projectID: UUID!
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
@ -4558,6 +4605,21 @@ func (ec *executionContext) field_Mutation_sortTaskGroup_args(ctx context.Contex
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_toggleProjectVisibility_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 ToggleProjectVisibility
|
||||
if tmp, ok := rawArgs["input"]; ok {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input"))
|
||||
arg0, err = ec.unmarshalNToggleProjectVisibility2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibility(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["input"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_toggleTaskLabel_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
@ -7744,6 +7806,80 @@ func (ec *executionContext) _Mutation_updateProjectName(ctx context.Context, fie
|
||||
return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐProject(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_toggleProjectVisibility(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: "Mutation",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.field_Mutation_toggleProjectVisibility_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.Mutation().ToggleProjectVisibility(rctx, args["input"].(ToggleProjectVisibility))
|
||||
}
|
||||
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||
roles, err := ec.unmarshalNRoleLevel2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleLevelᚄ(ctx, []interface{}{"ADMIN"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
level, err := ec.unmarshalNActionLevel2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐActionLevel(ctx, "PROJECT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
|
||||
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, roles, level, typeArg)
|
||||
}
|
||||
|
||||
tmp, err := directive1(rctx)
|
||||
if err != nil {
|
||||
return nil, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
if tmp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if data, ok := tmp.(*ToggleProjectVisibilityPayload); ok {
|
||||
return data, nil
|
||||
}
|
||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/jordanknott/taskcafe/internal/graph.ToggleProjectVisibilityPayload`, 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.(*ToggleProjectVisibilityPayload)
|
||||
fc.Result = res
|
||||
return ec.marshalNToggleProjectVisibilityPayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibilityPayload(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_createProjectLabel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -12601,6 +12737,38 @@ func (ec *executionContext) _Project_invitedMembers(ctx context.Context, field g
|
||||
return ec.marshalNInvitedMember2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐInvitedMemberᚄ(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Project_publicOn(ctx context.Context, field graphql.CollectedField, obj *db.Project) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Project",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
}
|
||||
|
||||
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 ec.resolvers.Project().PublicOn(rctx, obj)
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*time.Time)
|
||||
fc.Result = res
|
||||
return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Project_permission(ctx context.Context, field graphql.CollectedField, obj *db.Project) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -13224,40 +13392,8 @@ func (ec *executionContext) _Query_findProject(ctx context.Context, field graphq
|
||||
}
|
||||
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().FindProject(rctx, args["input"].(FindProject))
|
||||
}
|
||||
directive1 := func(ctx context.Context) (interface{}, error) {
|
||||
roles, err := ec.unmarshalNRoleLevel2ᚕgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleLevelᚄ(ctx, []interface{}{"ADMIN", "MEMBER"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
level, err := ec.unmarshalNActionLevel2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐActionLevel(ctx, "PROJECT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeArg, err := ec.unmarshalNObjectType2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐObjectType(ctx, "PROJECT")
|
||||
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, roles, level, typeArg)
|
||||
}
|
||||
|
||||
tmp, err := directive1(rctx)
|
||||
if err != nil {
|
||||
return nil, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
if tmp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if data, ok := tmp.(*db.Project); ok {
|
||||
return data, nil
|
||||
}
|
||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/jordanknott/taskcafe/internal/db.Project`, tmp)
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Query().FindProject(rctx, args["input"].(FindProject))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
@ -13572,14 +13708,11 @@ func (ec *executionContext) _Query_me(ctx context.Context, field graphql.Collect
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*MePayload)
|
||||
fc.Result = res
|
||||
return ec.marshalNMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx, field.Selections, res)
|
||||
return ec.marshalOMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_notifications(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
@ -15885,6 +16018,41 @@ func (ec *executionContext) _TeamRole_roleCode(ctx context.Context, field graphq
|
||||
return ec.marshalNRoleCode2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐRoleCode(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ToggleProjectVisibilityPayload_project(ctx context.Context, field graphql.CollectedField, obj *ToggleProjectVisibilityPayload) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "ToggleProjectVisibilityPayload",
|
||||
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.Project, 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.(*db.Project)
|
||||
fc.Result = res
|
||||
return ec.marshalNProject2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋdbᚐProject(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ToggleTaskLabelPayload_active(ctx context.Context, field graphql.CollectedField, obj *ToggleTaskLabelPayload) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -19238,6 +19406,34 @@ func (ec *executionContext) unmarshalInputTaskPositionUpdate(ctx context.Context
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputToggleProjectVisibility(ctx context.Context, obj interface{}) (ToggleProjectVisibility, error) {
|
||||
var it ToggleProjectVisibility
|
||||
var asMap = obj.(map[string]interface{})
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
case "projectID":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("projectID"))
|
||||
it.ProjectID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "isPublic":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("isPublic"))
|
||||
it.IsPublic, err = ec.unmarshalNBoolean2bool(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputToggleTaskLabelInput(ctx context.Context, obj interface{}) (ToggleTaskLabelInput, error) {
|
||||
var it ToggleTaskLabelInput
|
||||
var asMap = obj.(map[string]interface{})
|
||||
@ -20841,6 +21037,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "toggleProjectVisibility":
|
||||
out.Values[i] = ec._Mutation_toggleProjectVisibility(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "createProjectLabel":
|
||||
out.Values[i] = ec._Mutation_createProjectLabel(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
@ -21541,6 +21742,17 @@ func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet,
|
||||
}
|
||||
return res
|
||||
})
|
||||
case "publicOn":
|
||||
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._Project_publicOn(ctx, field, obj)
|
||||
return res
|
||||
})
|
||||
case "permission":
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
@ -21939,9 +22151,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
}
|
||||
}()
|
||||
res = ec._Query_me(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
return res
|
||||
})
|
||||
case "notifications":
|
||||
@ -22860,6 +23069,33 @@ func (ec *executionContext) _TeamRole(ctx context.Context, sel ast.SelectionSet,
|
||||
return out
|
||||
}
|
||||
|
||||
var toggleProjectVisibilityPayloadImplementors = []string{"ToggleProjectVisibilityPayload"}
|
||||
|
||||
func (ec *executionContext) _ToggleProjectVisibilityPayload(ctx context.Context, sel ast.SelectionSet, obj *ToggleProjectVisibilityPayload) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, toggleProjectVisibilityPayloadImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("ToggleProjectVisibilityPayload")
|
||||
case "project":
|
||||
out.Values[i] = ec._ToggleProjectVisibilityPayload_project(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
var toggleTaskLabelPayloadImplementors = []string{"ToggleTaskLabelPayload"}
|
||||
|
||||
func (ec *executionContext) _ToggleTaskLabelPayload(ctx context.Context, sel ast.SelectionSet, obj *ToggleTaskLabelPayload) graphql.Marshaler {
|
||||
@ -24186,20 +24422,6 @@ func (ec *executionContext) unmarshalNLogoutUser2githubᚗcomᚋjordanknottᚋta
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNMePayload2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx context.Context, sel ast.SelectionSet, v MePayload) graphql.Marshaler {
|
||||
return ec._MePayload(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx context.Context, sel ast.SelectionSet, v *MePayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._MePayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNMember2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMember(ctx context.Context, sel ast.SelectionSet, v Member) graphql.Marshaler {
|
||||
return ec._Member(ctx, sel, &v)
|
||||
}
|
||||
@ -25468,6 +25690,25 @@ func (ec *executionContext) marshalNTime2ᚖtimeᚐTime(ctx context.Context, sel
|
||||
return res
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNToggleProjectVisibility2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibility(ctx context.Context, v interface{}) (ToggleProjectVisibility, error) {
|
||||
res, err := ec.unmarshalInputToggleProjectVisibility(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNToggleProjectVisibilityPayload2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibilityPayload(ctx context.Context, sel ast.SelectionSet, v ToggleProjectVisibilityPayload) graphql.Marshaler {
|
||||
return ec._ToggleProjectVisibilityPayload(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNToggleProjectVisibilityPayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleProjectVisibilityPayload(ctx context.Context, sel ast.SelectionSet, v *ToggleProjectVisibilityPayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._ToggleProjectVisibilityPayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNToggleTaskLabelInput2githubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐToggleTaskLabelInput(ctx context.Context, v interface{}) (ToggleTaskLabelInput, error) {
|
||||
res, err := ec.unmarshalInputToggleTaskLabelInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
@ -26081,6 +26322,13 @@ func (ec *executionContext) unmarshalODeleteTaskComment2ᚖgithubᚗcomᚋjordan
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOMePayload2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐMePayload(ctx context.Context, sel ast.SelectionSet, v *MePayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._MePayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOProfileIcon2ᚖgithubᚗcomᚋjordanknottᚋtaskcafeᚋinternalᚋgraphᚐProfileIcon(ctx context.Context, sel ast.SelectionSet, v *ProfileIcon) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
|
@ -46,6 +46,12 @@ func NewHandler(repo db.Repository, emailConfig utils.EmailConfig) http.Handler
|
||||
}
|
||||
*/
|
||||
|
||||
userID, ok := GetUserID(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New("user must be logged in")
|
||||
}
|
||||
log.Info("has role")
|
||||
|
||||
var subjectID uuid.UUID
|
||||
in := graphql.GetFieldContext(ctx).Args["input"]
|
||||
val := reflect.ValueOf(in) // could be any underlying type
|
||||
@ -78,7 +84,7 @@ func NewHandler(repo db.Repository, emailConfig utils.EmailConfig) http.Handler
|
||||
// TODO: add config setting to disable personal projects
|
||||
return next(ctx)
|
||||
}
|
||||
subjectID, ok := subjectField.Interface().(uuid.UUID)
|
||||
subjectID, ok = subjectField.Interface().(uuid.UUID)
|
||||
if !ok {
|
||||
logger.New(ctx).Error("error while casting subject UUID")
|
||||
return nil, errors.New("error while casting subject uuid")
|
||||
@ -130,10 +136,6 @@ func NewHandler(repo db.Repository, emailConfig utils.EmailConfig) http.Handler
|
||||
},
|
||||
}
|
||||
} else if level == ActionLevelTeam {
|
||||
userID, ok := GetUserID(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New("user id is missing")
|
||||
}
|
||||
role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID})
|
||||
if err != nil {
|
||||
logger.New(ctx).WithError(err).Error("error while getting team roles for user ID")
|
||||
@ -270,3 +272,23 @@ const (
|
||||
TASK_CHECKLIST_ADDED int32 = 9
|
||||
TASK_CHECKLIST_REMOVED int32 = 10
|
||||
)
|
||||
|
||||
func NotAuthorized() error {
|
||||
return &gqlerror.Error{
|
||||
Message: "Not authorized",
|
||||
Extensions: map[string]interface{}{
|
||||
"code": "UNAUTHENTICATED",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func IsProjectPublic(ctx context.Context, repo db.Repository, projectID uuid.UUID) (bool, error) {
|
||||
publicOn, err := repo.GetPublicOn(ctx, projectID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !publicOn.Valid {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
@ -448,6 +448,15 @@ type TeamRole struct {
|
||||
RoleCode RoleCode `json:"roleCode"`
|
||||
}
|
||||
|
||||
type ToggleProjectVisibility struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
IsPublic bool `json:"isPublic"`
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload struct {
|
||||
Project *db.Project `json:"project"`
|
||||
}
|
||||
|
||||
type ToggleTaskLabelInput struct {
|
||||
TaskID uuid.UUID `json:"taskID"`
|
||||
ProjectLabelID uuid.UUID `json:"projectLabelID"`
|
||||
|
@ -119,6 +119,7 @@ type Project {
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
invitedMembers: [InvitedMember!]!
|
||||
publicOn: Time
|
||||
permission: ProjectPermission!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
@ -255,6 +256,7 @@ enum ObjectType {
|
||||
}
|
||||
|
||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
|
||||
directive @requiresUser on FIELD_DEFINITION
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
@ -262,7 +264,7 @@ type Query {
|
||||
invitedUsers: [InvitedUserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!):
|
||||
Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
|
||||
Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
@ -270,7 +272,7 @@ type Query {
|
||||
myTasks(input: MyTasks!): MyTasksPayload!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: MePayload!
|
||||
me: MePayload
|
||||
}
|
||||
|
||||
|
||||
@ -388,6 +390,16 @@ extend type Mutation {
|
||||
DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateProjectName(input: UpdateProjectName):
|
||||
Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleProjectVisibility(input: ToggleProjectVisibility!): ToggleProjectVisibilityPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input ToggleProjectVisibility {
|
||||
projectID: UUID!
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
@ -982,3 +994,4 @@ type DeleteUserAccountPayload {
|
||||
ok: Boolean!
|
||||
userAccount: UserAccount!
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,15 @@ func (r *mutationResolver) UpdateProjectName(ctx context.Context, input *UpdateP
|
||||
return &project, nil
|
||||
}
|
||||
|
||||
func (r *mutationResolver) ToggleProjectVisibility(ctx context.Context, input ToggleProjectVisibility) (*ToggleProjectVisibilityPayload, error) {
|
||||
if input.IsPublic {
|
||||
project, err := r.Repository.SetPublicOn(ctx, db.SetPublicOnParams{ProjectID: input.ProjectID, PublicOn: sql.NullTime{Valid: true, Time: time.Now().UTC()}})
|
||||
return &ToggleProjectVisibilityPayload{Project: &project}, err
|
||||
}
|
||||
project, err := r.Repository.SetPublicOn(ctx, db.SetPublicOnParams{ProjectID: input.ProjectID, PublicOn: sql.NullTime{Valid: false, Time: time.Time{}}})
|
||||
return &ToggleProjectVisibilityPayload{Project: &project}, err
|
||||
}
|
||||
|
||||
func (r *mutationResolver) CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*db.ProjectLabel, error) {
|
||||
createdAt := time.Now().UTC()
|
||||
|
||||
@ -1206,6 +1215,13 @@ func (r *projectResolver) InvitedMembers(ctx context.Context, obj *db.Project) (
|
||||
return invited, err
|
||||
}
|
||||
|
||||
func (r *projectResolver) PublicOn(ctx context.Context, obj *db.Project) (*time.Time, error) {
|
||||
if obj.PublicOn.Valid {
|
||||
return &obj.PublicOn.Time, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *projectResolver) Permission(ctx context.Context, obj *db.Project) (*ProjectPermission, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
@ -1277,12 +1293,19 @@ func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserA
|
||||
|
||||
func (r *queryResolver) FindProject(ctx context.Context, input FindProject) (*db.Project, error) {
|
||||
logger.New(ctx).Info("finding project user")
|
||||
_, isLoggedIn := GetUser(ctx)
|
||||
if !isLoggedIn {
|
||||
isPublic, _ := IsProjectPublic(ctx, r.Repository, input.ProjectID)
|
||||
if !isPublic {
|
||||
return &db.Project{}, NotAuthorized()
|
||||
}
|
||||
}
|
||||
project, err := r.Repository.GetProjectByID(ctx, input.ProjectID)
|
||||
if err == sql.ErrNoRows {
|
||||
return &db.Project{}, &gqlerror.Error{
|
||||
Message: "Project not found",
|
||||
Extensions: map[string]interface{}{
|
||||
"code": "11-404",
|
||||
"code": "NOT_FOUND",
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1497,7 +1520,7 @@ func (r *queryResolver) TaskGroups(ctx context.Context) ([]db.TaskGroup, error)
|
||||
func (r *queryResolver) Me(ctx context.Context) (*MePayload, error) {
|
||||
userID, ok := GetUserID(ctx)
|
||||
if !ok {
|
||||
return &MePayload{}, fmt.Errorf("internal server error")
|
||||
return nil, nil
|
||||
}
|
||||
user, err := r.Repository.GetUserAccountByID(ctx, userID)
|
||||
if err == sql.ErrNoRows {
|
||||
|
@ -119,6 +119,7 @@ type Project {
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
invitedMembers: [InvitedMember!]!
|
||||
publicOn: Time
|
||||
permission: ProjectPermission!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ enum ObjectType {
|
||||
}
|
||||
|
||||
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
|
||||
directive @requiresUser on FIELD_DEFINITION
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
@ -32,7 +33,7 @@ type Query {
|
||||
invitedUsers: [InvitedUserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!):
|
||||
Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
|
||||
Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
@ -40,7 +41,7 @@ type Query {
|
||||
myTasks(input: MyTasks!): MyTasksPayload!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: MePayload!
|
||||
me: MePayload
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,6 +4,16 @@ extend type Mutation {
|
||||
DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateProjectName(input: UpdateProjectName):
|
||||
Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleProjectVisibility(input: ToggleProjectVisibility!): ToggleProjectVisibilityPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input ToggleProjectVisibility {
|
||||
projectID: UUID!
|
||||
isPublic: Boolean!
|
||||
}
|
||||
|
||||
type ToggleProjectVisibilityPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
|
@ -18,6 +18,7 @@ type AuthenticationMiddleware struct {
|
||||
// Middleware returns the middleware handler
|
||||
func (m *AuthenticationMiddleware) Middleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Info("middleware")
|
||||
requestID := uuid.New()
|
||||
foundToken := true
|
||||
tokenRaw := ""
|
||||
@ -25,42 +26,26 @@ func (m *AuthenticationMiddleware) Middleware(next http.Handler) http.Handler {
|
||||
if err != nil {
|
||||
if err == http.ErrNoCookie {
|
||||
foundToken = false
|
||||
} else {
|
||||
log.WithError(err).Error("unknown error")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
if !foundToken {
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
log.WithError(err).Error("no auth token found in cookie or authorization header")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
if token != "" {
|
||||
tokenRaw = token
|
||||
}
|
||||
tokenRaw = token
|
||||
} else {
|
||||
tokenRaw = c.Value
|
||||
}
|
||||
authTokenID := uuid.MustParse(tokenRaw)
|
||||
token, err := m.repo.GetAuthTokenByID(r.Context(), authTokenID)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{
|
||||
"data": {},
|
||||
"errors": [
|
||||
{
|
||||
"extensions": {
|
||||
"code": "UNAUTHENTICATED"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`))
|
||||
return
|
||||
authTokenID, err := uuid.Parse(tokenRaw)
|
||||
log.Info("checking if logged in")
|
||||
ctx := r.Context()
|
||||
if err == nil {
|
||||
token, err := m.repo.GetAuthTokenByID(r.Context(), authTokenID)
|
||||
if err == nil {
|
||||
ctx = context.WithValue(ctx, utils.UserIDKey, token.UserID)
|
||||
}
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), utils.UserIDKey, token.UserID)
|
||||
// ctx = context.WithValue(ctx, utils.RestrictedModeKey, accessClaims.Restricted)
|
||||
// ctx = context.WithValue(ctx, utils.OrgRoleKey, accessClaims.OrgRole)
|
||||
ctx = context.WithValue(ctx, utils.ReqIDKey, requestID)
|
||||
|
Reference in New Issue
Block a user