Skip to content

Commit

Permalink
[Extend Governor APIs] User Extension Resources (#86)
Browse files Browse the repository at this point in the history
* add user extension resources

add audits and events

add tests

add user extension resource client

add user extension resource client

* Update pkg/api/v1alpha1/errors.go

Co-authored-by: Jacob See <5027680+jacobsee@users.noreply.github.com>

---------

Co-authored-by: Jacob See <5027680+jacobsee@users.noreply.github.com>
  • Loading branch information
bailinhe and jacobsee authored Oct 20, 2023
1 parent b961a23 commit 1e70e41
Show file tree
Hide file tree
Showing 10 changed files with 3,470 additions and 36 deletions.
57 changes: 57 additions & 0 deletions internal/dbtools/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -1183,3 +1183,60 @@ func AuditSystemExtensionResourceDeleted(ctx context.Context, exec boil.ContextE

return &event, event.Insert(ctx, exec, boil.Infer())
}

// AuditUserExtensionResourceCreated inserts an event representing an extension resource being created
func AuditUserExtensionResourceCreated(ctx context.Context, exec boil.ContextExecutor, pID string, actor *models.User, a *models.UserExtensionResource) (*models.AuditEvent, error) {
// TODO non-user API actors don't exist in the governor database,
// we need to figure out how to handle that relationship in the audit table
var actorID null.String
if actor != nil {
actorID = null.StringFrom(actor.ID)
}

event := models.AuditEvent{
ParentID: null.StringFrom(pID),
ActorID: actorID,
Action: "extension.resource.created",
Changeset: calculateChangeset(&models.UserExtensionResource{}, a),
}

return &event, event.Insert(ctx, exec, boil.Infer())
}

// AuditUserExtensionResourceUpdated inserts an event representing a extension being created
func AuditUserExtensionResourceUpdated(ctx context.Context, exec boil.ContextExecutor, pID string, actor *models.User, o, a *models.UserExtensionResource) (*models.AuditEvent, error) {
// TODO non-user API actors don't exist in the governor database,
// we need to figure out how to handle that relationship in the audit table
var actorID null.String
if actor != nil {
actorID = null.StringFrom(actor.ID)
}

event := models.AuditEvent{
ParentID: null.StringFrom(pID),
ActorID: actorID,
Action: "extension.resource.updated",
Changeset: calculateChangeset(o, a),
}

return &event, event.Insert(ctx, exec, boil.Infer())
}

// AuditUserExtensionResourceDeleted inserts an event representing an extension being deleted
func AuditUserExtensionResourceDeleted(ctx context.Context, exec boil.ContextExecutor, pID string, actor *models.User, a *models.UserExtensionResource) (*models.AuditEvent, error) {
// TODO non-user API actors don't exist in the governor database,
// we need to figure out how to handle that relationship in the audit table
var actorID null.String
if actor != nil {
actorID = null.StringFrom(actor.ID)
}

event := models.AuditEvent{
ParentID: null.StringFrom(pID),
ActorID: actorID,
Action: "extension.resource.deleted",
Changeset: calculateChangeset(a, &models.UserExtensionResource{}),
}

return &event, event.Insert(ctx, exec, boil.Infer())
}
6 changes: 6 additions & 0 deletions pkg/api/v1alpha1/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ var (
ErrExtensionNotFound = errors.New("extension does not exist")
// ErrERDNotFound is returned when an extension resource definition is not found
ErrERDNotFound = errors.New("ERD does not exist")
// ErrNoUserProvided is returned when no user is provided
ErrNoUserProvided = errors.New("neither user-id nor context user were provided")
// ErrExtensionResourceNotFound is returned when an extension resource is not found
ErrExtensionResourceNotFound = errors.New("extension resource does not exist")
// ErrUserNotFound is returned when a user is not found
ErrUserNotFound = errors.New("user does not exist")
)

func sendError(c *gin.Context, code int, msg string) {
Expand Down
81 changes: 81 additions & 0 deletions pkg/api/v1alpha1/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,87 @@ func (r *Router) Routes(rg *gin.RouterGroup) {
r.AuthMW.AuthRequired(createScopesWithOpenID("governor:extensionresources")),
r.deleteSystemExtensionResource,
)

// user extension resources
rg.POST(
"/users/:id/extension-resources/:ex-slug/:erd-slug-plural/:erd-version",
r.AuditMW.AuditWithType("CreateUserExtensionResource"),
r.AuthMW.AuthRequired(createScopesWithOpenID("governor:users")),
r.mwUserAuthRequired(AuthRoleAdmin),
r.createUserExtensionResource,
)

rg.POST(
"/user/extension-resources/:ex-slug/:erd-slug-plural/:erd-version",
r.AuditMW.AuditWithType("CreateAuthenticatedUserExtensionResource"),
r.AuthMW.AuthRequired([]string{oidcScope}),
r.mwUserAuthRequired(AuthRoleUser),
r.createUserExtensionResource,
)

rg.GET(
"/users/:id/extension-resources/:ex-slug/:erd-slug-plural/:erd-version",
r.AuditMW.AuditWithType("ListUserExtensionResources"),
r.AuthMW.AuthRequired(readScopesWithOpenID("governor:users")),
r.mwUserAuthRequired(AuthRoleAdmin),
r.listUserExtensionResources,
)

rg.GET(
"/user/extension-resources/:ex-slug/:erd-slug-plural/:erd-version",
r.AuditMW.AuditWithType("ListAuthenticatedUserExtensionResources"),
r.AuthMW.AuthRequired([]string{oidcScope}),
r.mwUserAuthRequired(AuthRoleUser),
r.listUserExtensionResources,
)

rg.GET(
"/users/:id/extension-resources/:ex-slug/:erd-slug-plural/:erd-version/:resource-id",
r.AuditMW.AuditWithType("GetUserExtensionResource"),
r.AuthMW.AuthRequired(readScopesWithOpenID("governor:users")),
r.mwUserAuthRequired(AuthRoleAdmin),
r.getUserExtensionResource,
)

rg.GET(
"/user/extension-resources/:ex-slug/:erd-slug-plural/:erd-version/:resource-id",
r.AuditMW.AuditWithType("GetAuthenticatedUserExtensionResources"),
r.AuthMW.AuthRequired([]string{oidcScope}),
r.mwUserAuthRequired(AuthRoleUser),
r.getUserExtensionResource,
)

rg.PATCH(
"/users/:id/extension-resources/:ex-slug/:erd-slug-plural/:erd-version/:resource-id",
r.AuditMW.AuditWithType("UpdateUserExtensionResource"),
r.AuthMW.AuthRequired(updateScopesWithOpenID("governor:users")),
r.mwUserAuthRequired(AuthRoleAdmin),
r.updateUserExtensionResource,
)

rg.PATCH(
"/user/extension-resources/:ex-slug/:erd-slug-plural/:erd-version/:resource-id",
r.AuditMW.AuditWithType("UpdateAuthenticatedUserExtensionResources"),
r.AuthMW.AuthRequired([]string{oidcScope}),
r.mwUserAuthRequired(AuthRoleUser),
r.updateUserExtensionResource,
)

rg.DELETE(
"/users/:id/extension-resources/:ex-slug/:erd-slug-plural/:erd-version/:resource-id",
r.AuditMW.AuditWithType("DeleteUserExtensionResource"),
r.AuthMW.AuthRequired(deleteScopesWithOpenID("governor:users")),
r.mwUserAuthRequired(AuthRoleAdmin),
r.deleteUserExtensionResource,
)

rg.DELETE(
"/user/extension-resources/:ex-slug/:erd-slug-plural/:erd-version/:resource-id",
r.AuditMW.AuditWithType("DeleteAuthenticatedUserExtensionResources"),
r.AuthMW.AuthRequired([]string{oidcScope}),
r.mwUserAuthRequired(AuthRoleUser),
r.deleteUserExtensionResource,
)
}

func contains(list []string, item string) bool {
Expand Down
Loading

0 comments on commit 1e70e41

Please sign in to comment.