mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat: add organization scope for shared ports (#18314)
This commit is contained in:
@ -15,25 +15,12 @@ func NewEnterprisePortSharer() *EnterprisePortSharer {
|
||||
|
||||
func (EnterprisePortSharer) AuthorizedLevel(template database.Template, level codersdk.WorkspaceAgentPortShareLevel) error {
|
||||
maxLevel := codersdk.WorkspaceAgentPortShareLevel(template.MaxPortSharingLevel)
|
||||
switch level {
|
||||
case codersdk.WorkspaceAgentPortShareLevelPublic:
|
||||
if maxLevel != codersdk.WorkspaceAgentPortShareLevelPublic {
|
||||
return xerrors.Errorf("port sharing level not allowed. Max level is '%s'", maxLevel)
|
||||
}
|
||||
case codersdk.WorkspaceAgentPortShareLevelAuthenticated:
|
||||
if maxLevel == codersdk.WorkspaceAgentPortShareLevelOwner {
|
||||
return xerrors.Errorf("port sharing level not allowed. Max level is '%s'", maxLevel)
|
||||
}
|
||||
default:
|
||||
return xerrors.New("port sharing level is invalid.")
|
||||
}
|
||||
|
||||
return nil
|
||||
return level.IsCompatibleWithMaxLevel(maxLevel)
|
||||
}
|
||||
|
||||
func (EnterprisePortSharer) ValidateTemplateMaxLevel(level codersdk.WorkspaceAgentPortShareLevel) error {
|
||||
if !level.ValidMaxLevel() {
|
||||
return xerrors.New("invalid max port sharing level, value must be 'authenticated' or 'public'.")
|
||||
return xerrors.New("invalid max port sharing level, value must be 'authenticated', 'organization', or 'public'.")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -8,23 +8,20 @@ import (
|
||||
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
"github.com/coder/coder/v2/coderd/util/ptr"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/license"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
func TestWorkspacePortShare(t *testing.T) {
|
||||
func TestWorkspacePortSharePublic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
},
|
||||
Options: &coderdtest.Options{IncludeProvisionerDaemon: true},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureControlSharedPorts: 1,
|
||||
},
|
||||
Features: license.Features{codersdk.FeatureControlSharedPorts: 1},
|
||||
},
|
||||
})
|
||||
client, user := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
||||
@ -35,8 +32,12 @@ func TestWorkspacePortShare(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
// try to update port share with template max port share level owner
|
||||
_, err := client.UpsertWorkspaceAgentPortShare(ctx, r.workspace.ID, codersdk.UpsertWorkspaceAgentPortShareRequest{
|
||||
templ, err := client.Template(ctx, r.workspace.TemplateID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, templ.MaxPortShareLevel, codersdk.WorkspaceAgentPortShareLevelOwner)
|
||||
|
||||
// Try to update port share with template max port share level owner.
|
||||
_, err = client.UpsertWorkspaceAgentPortShare(ctx, r.workspace.ID, codersdk.UpsertWorkspaceAgentPortShareRequest{
|
||||
AgentName: r.sdkAgent.Name,
|
||||
Port: 8080,
|
||||
ShareLevel: codersdk.WorkspaceAgentPortShareLevelPublic,
|
||||
@ -44,10 +45,9 @@ func TestWorkspacePortShare(t *testing.T) {
|
||||
})
|
||||
require.Error(t, err, "Port sharing level not allowed")
|
||||
|
||||
// update the template max port share level to public
|
||||
var level codersdk.WorkspaceAgentPortShareLevel = codersdk.WorkspaceAgentPortShareLevelPublic
|
||||
// Update the template max port share level to public
|
||||
client.UpdateTemplateMeta(ctx, r.workspace.TemplateID, codersdk.UpdateTemplateMeta{
|
||||
MaxPortShareLevel: &level,
|
||||
MaxPortShareLevel: ptr.Ref(codersdk.WorkspaceAgentPortShareLevelPublic),
|
||||
})
|
||||
|
||||
// OK
|
||||
@ -60,3 +60,58 @@ func TestWorkspacePortShare(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, codersdk.WorkspaceAgentPortShareLevelPublic, ps.ShareLevel)
|
||||
}
|
||||
|
||||
func TestWorkspacePortShareOrganization(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ownerClient, owner := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{IncludeProvisionerDaemon: true},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{codersdk.FeatureControlSharedPorts: 1},
|
||||
},
|
||||
})
|
||||
client, user := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
||||
r := setupWorkspaceAgent(t, client, codersdk.CreateFirstUserResponse{
|
||||
UserID: user.ID,
|
||||
OrganizationID: owner.OrganizationID,
|
||||
}, 0)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
templ, err := client.Template(ctx, r.workspace.TemplateID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, templ.MaxPortShareLevel, codersdk.WorkspaceAgentPortShareLevelOwner)
|
||||
|
||||
// Try to update port share with template max port share level owner
|
||||
_, err = client.UpsertWorkspaceAgentPortShare(ctx, r.workspace.ID, codersdk.UpsertWorkspaceAgentPortShareRequest{
|
||||
AgentName: r.sdkAgent.Name,
|
||||
Port: 8080,
|
||||
ShareLevel: codersdk.WorkspaceAgentPortShareLevelOrganization,
|
||||
Protocol: codersdk.WorkspaceAgentPortShareProtocolHTTP,
|
||||
})
|
||||
require.Error(t, err, "Port sharing level not allowed")
|
||||
|
||||
// Update the template max port share level to organization
|
||||
client.UpdateTemplateMeta(ctx, r.workspace.TemplateID, codersdk.UpdateTemplateMeta{
|
||||
MaxPortShareLevel: ptr.Ref(codersdk.WorkspaceAgentPortShareLevelOrganization),
|
||||
})
|
||||
|
||||
// Try to share a port publicly with template max port share level organization
|
||||
_, err = client.UpsertWorkspaceAgentPortShare(ctx, r.workspace.ID, codersdk.UpsertWorkspaceAgentPortShareRequest{
|
||||
AgentName: r.sdkAgent.Name,
|
||||
Port: 8080,
|
||||
ShareLevel: codersdk.WorkspaceAgentPortShareLevelPublic,
|
||||
Protocol: codersdk.WorkspaceAgentPortShareProtocolHTTP,
|
||||
})
|
||||
require.Error(t, err, "Port sharing level not allowed")
|
||||
|
||||
// OK
|
||||
ps, err := client.UpsertWorkspaceAgentPortShare(ctx, r.workspace.ID, codersdk.UpsertWorkspaceAgentPortShareRequest{
|
||||
AgentName: r.sdkAgent.Name,
|
||||
Port: 8080,
|
||||
ShareLevel: codersdk.WorkspaceAgentPortShareLevelOrganization,
|
||||
Protocol: codersdk.WorkspaceAgentPortShareProtocolHTTP,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, codersdk.WorkspaceAgentPortShareLevelOrganization, ps.ShareLevel)
|
||||
}
|
||||
|
Reference in New Issue
Block a user