Skip to content

Commit

Permalink
Merge pull request #383 from hashicorp/gs/add-run-task-permissions
Browse files Browse the repository at this point in the history
Add Run Tasks permissions for Org. and Workspace
  • Loading branch information
glennsarti committed May 4, 2022
2 parents 6115330 + 94b9c8d commit a5bcb84
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 0 deletions.
1 change: 1 addition & 0 deletions organization.go
Expand Up @@ -113,6 +113,7 @@ type OrganizationPermissions struct {
CanCreateWorkspace bool `jsonapi:"attr,can-create-workspace"`
CanCreateWorkspaceMigration bool `jsonapi:"attr,can-create-workspace-migration"`
CanDestroy bool `jsonapi:"attr,can-destroy"`
CanManageRunTasks bool `jsonapi:"attr,can-manage-run-tasks"`
CanTraverse bool `jsonapi:"attr,can-traverse"`
CanUpdate bool `jsonapi:"attr,can-update"`
CanUpdateAPIToken bool `jsonapi:"attr,can-update-api-token"`
Expand Down
22 changes: 22 additions & 0 deletions organization_integration_test.go
Expand Up @@ -459,3 +459,25 @@ func TestOrganization_Unmarshal(t *testing.T) {
assert.NotEmpty(t, org.Permissions)
assert.Equal(t, org.Permissions.CanCreateTeam, true)
}

func TestOrganizationsReadRunTasksPermission(t *testing.T) {
skipIfFreeOnly(t)
skipIfBeta(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

t.Run("when the org exists", func(t *testing.T) {
org, err := client.Organizations.Read(ctx, orgTest.Name)
require.NoError(t, err)
assert.Equal(t, orgTest, org)
assert.NotEmpty(t, org.Permissions)

t.Run("permissions are properly decoded", func(t *testing.T) {
assert.True(t, org.Permissions.CanManageRunTasks)
})
})
}
2 changes: 2 additions & 0 deletions team.go
Expand Up @@ -64,6 +64,7 @@ type OrganizationAccess struct {
ManageVCSSettings bool `jsonapi:"attr,manage-vcs-settings"`
ManageProviders bool `jsonapi:"attr,manage-providers"`
ManageModules bool `jsonapi:"attr,manage-modules"`
ManageRunTasks bool `jsonapi:"attr,manage-run-tasks"`
}

// TeamPermissions represents the current user's permissions on the team.
Expand Down Expand Up @@ -139,6 +140,7 @@ type OrganizationAccessOptions struct {
ManageVCSSettings *bool `json:"manage-vcs-settings,omitempty"`
ManageProviders *bool `json:"manage-providers,omitempty"`
ManageModules *bool `json:"manage-modules,omitempty"`
ManageRunTasks *bool `json:"manage-run-tasks,omitempty"`
}

// List all the teams of the given organization.
Expand Down
3 changes: 3 additions & 0 deletions team_access.go
Expand Up @@ -98,6 +98,7 @@ type TeamAccess struct {
StateVersions StateVersionsPermissionType `jsonapi:"attr,state-versions"`
SentinelMocks SentinelMocksPermissionType `jsonapi:"attr,sentinel-mocks"`
WorkspaceLocking bool `jsonapi:"attr,workspace-locking"`
RunTasks bool `jsonapi:"attr,run-tasks"`

// Relations
Team *Team `jsonapi:"relation,team"`
Expand Down Expand Up @@ -128,6 +129,7 @@ type TeamAccessAddOptions struct {
StateVersions *StateVersionsPermissionType `jsonapi:"attr,state-versions,omitempty"`
SentinelMocks *SentinelMocksPermissionType `jsonapi:"attr,sentinel-mocks,omitempty"`
WorkspaceLocking *bool `jsonapi:"attr,workspace-locking,omitempty"`
RunTasks *bool `jsonapi:"attr,run-tasks,omitempty"`

// The team to add to the workspace
Team *Team `jsonapi:"relation,team"`
Expand All @@ -154,6 +156,7 @@ type TeamAccessUpdateOptions struct {
StateVersions *StateVersionsPermissionType `jsonapi:"attr,state-versions,omitempty"`
SentinelMocks *SentinelMocksPermissionType `jsonapi:"attr,sentinel-mocks,omitempty"`
WorkspaceLocking *bool `jsonapi:"attr,workspace-locking,omitempty"`
RunTasks *bool `jsonapi:"attr,run-tasks,omitempty"`
}

// List all the team accesses for a given workspace.
Expand Down
64 changes: 64 additions & 0 deletions team_access_integration_test.go
Expand Up @@ -338,3 +338,67 @@ func TestTeamAccessesRemove(t *testing.T) {
assert.Equal(t, err, ErrInvalidAccessTeamID)
})
}

func TestTeamAccessesReadRunTasks(t *testing.T) {
skipIfFreeOnly(t)
skipIfBeta(t)
skipIfEnterprise(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()
wTest, wTestCleanup := createWorkspace(t, client, orgTest)
defer wTestCleanup()
tmTest, tmTestCleanup := createTeam(t, client, orgTest)
defer tmTestCleanup()

taTest, taTestCleanup := createTeamAccess(t, client, tmTest, wTest, orgTest)
defer taTestCleanup()

t.Run("when the team access exists", func(t *testing.T) {
ta, err := client.TeamAccess.Read(ctx, taTest.ID)
require.NoError(t, err)

assert.Equal(t, AccessAdmin, ta.Access)

t.Run("permission attributes are decoded", func(t *testing.T) {
assert.Equal(t, true, ta.RunTasks)
})
})
}

func TestTeamAccessesUpdateRunTasks(t *testing.T) {
skipIfFreeOnly(t)
skipIfBeta(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

wTest, wTestCleanup := createWorkspace(t, client, orgTest)
defer wTestCleanup()

tmTest, tmTestCleanup := createTeam(t, client, orgTest)
defer tmTestCleanup()

taTest, taTestCleanup := createTeamAccess(t, client, tmTest, wTest, orgTest)
defer taTestCleanup()

t.Run("with valid attributes", func(t *testing.T) {
newAccess := !taTest.RunTasks
options := TeamAccessUpdateOptions{
Access: Access(AccessCustom),
RunTasks: &newAccess,
}

ta, err := client.TeamAccess.Update(ctx, taTest.ID, options)
require.NoError(t, err)

assert.Equal(t, AccessCustom, ta.Access)
assert.Equal(t, newAccess, ta.RunTasks)
})
}
42 changes: 42 additions & 0 deletions team_integration_test.go
Expand Up @@ -346,3 +346,45 @@ func TestTeamCreateOptions_Marshal(t *testing.T) {
`
assert.Equal(t, expectedBody, string(bodyBytes))
}

func TestTeamsUpdateRunTasks(t *testing.T) {
skipIfFreeOnly(t)
skipIfBeta(t)
skipIfEnterprise(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

tmTest, tmTestCleanup := createTeam(t, client, orgTest)
defer tmTestCleanup()

t.Run("with valid options", func(t *testing.T) {
options := TeamUpdateOptions{
Name: String("foo bar"),
OrganizationAccess: &OrganizationAccessOptions{
ManageRunTasks: Bool(true),
},
Visibility: String("organization"),
}

tm, err := client.Teams.Update(ctx, tmTest.ID, options)
require.NoError(t, err)

refreshed, err := client.Teams.Read(ctx, tmTest.ID)
require.NoError(t, err)

for _, item := range []*Team{
tm,
refreshed,
} {
assert.Equal(t, *options.Name, item.Name)
assert.Equal(t,
*options.OrganizationAccess.ManageRunTasks,
item.OrganizationAccess.ManageRunTasks,
)
}
})
}
1 change: 1 addition & 0 deletions workspace.go
Expand Up @@ -193,6 +193,7 @@ type WorkspacePermissions struct {
CanDestroy bool `jsonapi:"attr,can-destroy"`
CanForceUnlock bool `jsonapi:"attr,can-force-unlock"`
CanLock bool `jsonapi:"attr,can-lock"`
CanManageRunTasks bool `jsonapi:"attr,can-manage-run-tasks"`
CanQueueApply bool `jsonapi:"attr,can-queue-apply"`
CanQueueDestroy bool `jsonapi:"attr,can-queue-destroy"`
CanQueueRun bool `jsonapi:"attr,can-queue-run"`
Expand Down
21 changes: 21 additions & 0 deletions workspace_integration_test.go
Expand Up @@ -1414,3 +1414,24 @@ func TestWorkspaceCreateOptions_Marshal(t *testing.T) {
`
assert.Equal(t, expectedBody, string(bodyBytes))
}

func TestWorkspacesRunTasksPermission(t *testing.T) {
skipIfFreeOnly(t)
skipIfBeta(t)

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

wTest, wTestCleanup := createWorkspace(t, client, orgTest)
defer wTestCleanup()

t.Run("when the workspace exists", func(t *testing.T) {
w, err := client.Workspaces.Read(ctx, orgTest.Name, wTest.Name)
require.NoError(t, err)
assert.Equal(t, wTest, w)
assert.True(t, w.Permissions.CanManageRunTasks)
})
}

0 comments on commit a5bcb84

Please sign in to comment.