Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
permission.go3.57 kB
package rbac import ( "context" "fmt" "strings" "github.com/Southclaws/dt" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fctx" "github.com/Southclaws/fault/ftag" ) var ErrPermissions = fault.New("invalid permissions", ftag.With(ftag.PermissionDenied)) var readPermissions = []Permission{ PermissionReadPublishedThreads, PermissionReadPublishedLibrary, PermissionListProfiles, PermissionReadProfile, PermissionListCollections, PermissionReadCollection, } var writePermissions = []Permission{ PermissionCreatePost, PermissionCreateReaction, PermissionManagePosts, PermissionManageCategories, PermissionCreateInvitation, PermissionManageLibrary, PermissionSubmitLibraryNode, PermissionUploadAsset, PermissionManageEvents, PermissionCreateCollection, PermissionManageCollections, PermissionCollectionSubmit, PermissionUsePersonalAccessKeys, PermissionManageSettings, PermissionManageSuspensions, PermissionManageRoles, PermissionViewAccounts, PermissionAdministrator, } // Type Permission is generated by rbacgen, the source of truth is openapi.yaml. type PermissionList []Permission func (p PermissionList) String() string { s := make([]string, len(p)) for i, pp := range p { s[i] = pp.String() } return strings.Join(s, ",") } type Permissions struct { p PermissionList m map[Permission]struct{} } func NewPermissions(s []string) (*Permissions, error) { ps, err := dt.MapErr(s, NewPermission) if err != nil { return nil, err } list := NewList(ps...) return &list, nil } func (p Permissions) List() PermissionList { return p.p } func NewList(permissions ...Permission) Permissions { m := map[Permission]struct{}{} for _, p := range permissions { m[p] = struct{}{} } return Permissions{permissions, m} } func (p Permissions) HasAll(perms ...Permission) bool { for _, pp := range perms { if _, ok := p.m[pp]; !ok { return false } } return true } func (p Permissions) HasAny(perms ...Permission) bool { for _, pp := range perms { if _, ok := p.m[pp]; ok { return true } } return false } func (p Permissions) HasAnyWrite() bool { for _, pp := range writePermissions { if _, ok := p.m[pp]; ok { return true } } return false } func (p Permissions) HasAnyRead() bool { for _, pp := range readPermissions { if _, ok := p.m[pp]; ok { return true } } return false } // Authorise will check if the account holds any of the permissions provided. If // it does not, it then runs the additional check function in order to apply any // domain-specific logic such as resource ownership, to determine authorisation. func (p Permissions) Authorise(ctx context.Context, fn func() error, perms ...Permission) error { ctx = fctx.WithMeta(ctx, "permissions", PermissionList(perms).String(), ) // PermissionAdministrator can do anything. if p.HasAny(PermissionAdministrator) { return nil } // If permissions are valid, do not need to run additional check function. if p.HasAny(perms...) { return nil } // Additional check functions are for when permission requires logic, such // as checking for resource ownership or non-publishing draft submissions. if fn != nil { if err := fn(); err != nil { return fault.Wrap( fmt.Errorf("%w: additional check failed: %w", ErrPermissions, err), fctx.With(ctx), ftag.With(ftag.PermissionDenied), ) } // If the additional check function passes, override the missing perm. return nil } // No additional check and permission is missing. return fault.Wrap(ErrPermissions, fctx.With(ctx)) }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server