Skip to content

chore: refactor patch custom organization route to live in enterprise #14099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ func New(options *Options) *API {
TemplateScheduleStore: options.TemplateScheduleStore,
UserQuietHoursScheduleStore: options.UserQuietHoursScheduleStore,
AccessControlStore: options.AccessControlStore,
CustomRoleHandler: atomic.Pointer[CustomRoleHandler]{},
Experiments: experiments,
healthCheckGroup: &singleflight.Group[string, *healthsdk.HealthcheckReport]{},
Acquirer: provisionerdserver.NewAcquirer(
Expand All @@ -476,8 +475,6 @@ func New(options *Options) *API {
dbRolluper: options.DatabaseRolluper,
}

var customRoleHandler CustomRoleHandler = &agplCustomRoleHandler{}
api.CustomRoleHandler.Store(&customRoleHandler)
api.AppearanceFetcher.Store(&appearance.DefaultFetcher)
api.PortSharer.Store(&portsharing.DefaultPortSharer)
buildInfo := codersdk.BuildInfoResponse{
Expand Down Expand Up @@ -887,8 +884,6 @@ func New(options *Options) *API {
r.Get("/", api.listMembers)
r.Route("/roles", func(r chi.Router) {
r.Get("/", api.assignableOrgRoles)
r.With(httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentCustomRoles)).
Patch("/", api.patchOrgRoles)
})

r.Route("/{user}", func(r chi.Router) {
Expand Down Expand Up @@ -1327,8 +1322,6 @@ type API struct {
// passed to dbauthz.
AccessControlStore *atomic.Pointer[dbauthz.AccessControlStore]
PortSharer atomic.Pointer[portsharing.PortSharer]
// CustomRoleHandler is the AGPL/Enterprise implementation for custom roles.
CustomRoleHandler atomic.Pointer[CustomRoleHandler]

HTTPAuth *HTTPAuthorizer

Expand Down
47 changes: 0 additions & 47 deletions coderd/roles.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package coderd

import (
"context"
"net/http"

"github.com/google/uuid"
Expand All @@ -16,52 +15,6 @@ import (
"github.com/coder/coder/v2/coderd/rbac"
)

// CustomRoleHandler handles AGPL/Enterprise interface for handling custom
// roles. Ideally only included in the enterprise package, but the routes are
// intermixed with AGPL endpoints.
type CustomRoleHandler interface {
PatchOrganizationRole(ctx context.Context, rw http.ResponseWriter, r *http.Request, orgID uuid.UUID, role codersdk.PatchRoleRequest) (codersdk.Role, bool)
}

type agplCustomRoleHandler struct{}

func (agplCustomRoleHandler) PatchOrganizationRole(ctx context.Context, rw http.ResponseWriter, _ *http.Request, _ uuid.UUID, _ codersdk.PatchRoleRequest) (codersdk.Role, bool) {
httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
Message: "Creating and updating custom roles is an Enterprise feature. Contact sales!",
})
return codersdk.Role{}, false
}

// patchRole will allow creating a custom organization role
//
// @Summary Upsert a custom organization role
// @ID upsert-a-custom-organization-role
// @Security CoderSessionToken
// @Produce json
// @Param organization path string true "Organization ID" format(uuid)
// @Tags Members
// @Success 200 {array} codersdk.Role
// @Router /organizations/{organization}/members/roles [patch]
func (api *API) patchOrgRoles(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
handler = *api.CustomRoleHandler.Load()
organization = httpmw.OrganizationParam(r)
)

var req codersdk.PatchRoleRequest
if !httpapi.Read(ctx, rw, r, &req) {
return
}

updated, ok := handler.PatchOrganizationRole(ctx, rw, r, organization.ID, req)
if !ok {
return
}

httpapi.Write(ctx, rw, http.StatusOK, updated)
}

// AssignableSiteRoles returns all site wide roles that can be assigned.
//
// @Summary Get site member roles
Expand Down
38 changes: 35 additions & 3 deletions docs/api/members.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions docs/api/schemas.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions enterprise/coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
r.Delete("/organizations/{organization}", api.deleteOrganization)
})

r.Group(func(r chi.Router) {
r.Use(
apiKeyMiddleware,
api.RequireFeatureMW(codersdk.FeatureCustomRoles),
httpmw.RequireExperiment(api.AGPL.Experiments, codersdk.ExperimentCustomRoles),
httpmw.ExtractOrganizationParam(api.Database),
)
r.Patch("/organizations/{organization}/members/roles", api.patchOrgRoles)
})

r.Route("/organizations/{organization}/groups", func(r chi.Router) {
r.Use(
apiKeyMiddleware,
Expand Down Expand Up @@ -787,16 +797,6 @@ func (api *API) updateEntitlements(ctx context.Context) error {
api.AGPL.PortSharer.Store(&ps)
}

if initial, changed, enabled := featureChanged(codersdk.FeatureCustomRoles); shouldUpdate(initial, changed, enabled) {
var handler coderd.CustomRoleHandler = &enterpriseCustomRoleHandler{API: api, Enabled: enabled}
api.AGPL.CustomRoleHandler.Store(&handler)
}

if initial, changed, enabled := featureChanged(codersdk.FeatureMultipleOrganizations); shouldUpdate(initial, changed, enabled) {
var handler coderd.CustomRoleHandler = &enterpriseCustomRoleHandler{API: api, Enabled: enabled}
api.AGPL.CustomRoleHandler.Store(&handler)
}

// External token encryption is soft-enforced
featureExternalTokenEncryption := entitlements.Features[codersdk.FeatureExternalTokenEncryption]
featureExternalTokenEncryption.Enabled = len(api.ExternalTokenEncryption) > 0
Expand Down
Loading
Loading