add(sam): spec and scaffold of permissions api
This commit is contained in:
@@ -634,5 +634,78 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Permissions",
|
||||
"package": "sam",
|
||||
"parameters": {},
|
||||
"entrypoint": "permissions",
|
||||
"authentication": [
|
||||
"Client ID",
|
||||
"Session ID"
|
||||
],
|
||||
"apis": [
|
||||
{
|
||||
"name": "list",
|
||||
"path": "/permissions",
|
||||
"method": "GET",
|
||||
"title": "List default permissions",
|
||||
"parameters": {}
|
||||
},
|
||||
{
|
||||
"name": "getTeam",
|
||||
"path": "/permissions/{team}",
|
||||
"method": "GET",
|
||||
"title": "Retrieve current permission settings",
|
||||
"parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "team",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"title": "Team ID"
|
||||
}
|
||||
],
|
||||
"get": [
|
||||
{
|
||||
"name": "scope",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"title": "Permissions scope"
|
||||
},
|
||||
{
|
||||
"name": "resource",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"title": "Permissions resource"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "setTeam",
|
||||
"path": "/permissions/{team}",
|
||||
"method": "POST",
|
||||
"title": "Update permission settings",
|
||||
"parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "team",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"title": "Team ID"
|
||||
}
|
||||
],
|
||||
"post": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"type": "[]rbac.Permission",
|
||||
"required": true,
|
||||
"title": "List of permissions to set"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"Title": "Permissions",
|
||||
"Package": "sam",
|
||||
"Interface": "Permissions",
|
||||
"Struct": null,
|
||||
"Parameters": {},
|
||||
"Protocol": "",
|
||||
"Authentication": [
|
||||
"Client ID",
|
||||
"Session ID"
|
||||
],
|
||||
"Path": "/permissions",
|
||||
"APIs": [
|
||||
{
|
||||
"Name": "list",
|
||||
"Method": "GET",
|
||||
"Title": "List default permissions",
|
||||
"Path": "/permissions",
|
||||
"Parameters": {}
|
||||
},
|
||||
{
|
||||
"Name": "getTeam",
|
||||
"Method": "GET",
|
||||
"Title": "Retrieve current permission settings",
|
||||
"Path": "/permissions/{team}",
|
||||
"Parameters": {
|
||||
"get": [
|
||||
{
|
||||
"name": "scope",
|
||||
"required": true,
|
||||
"title": "Permissions scope",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "resource",
|
||||
"required": true,
|
||||
"title": "Permissions resource",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"name": "team",
|
||||
"required": true,
|
||||
"title": "Team ID",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "setTeam",
|
||||
"Method": "POST",
|
||||
"Title": "Update permission settings",
|
||||
"Path": "/permissions/{team}",
|
||||
"Parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "team",
|
||||
"required": true,
|
||||
"title": "Team ID",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"post": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"required": true,
|
||||
"title": "List of permissions to set",
|
||||
"type": "[]rbac.Permission"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -418,6 +418,55 @@ The following event types may be sent with a message event:
|
||||
|
||||
|
||||
|
||||
# Permissions
|
||||
|
||||
## List default permissions
|
||||
|
||||
#### Method
|
||||
|
||||
| URI | Protocol | Method | Authentication |
|
||||
| --- | -------- | ------ | -------------- |
|
||||
| `/permissions/permissions` | HTTP/S | GET | Client ID, Session ID |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Method | Description | Default | Required? |
|
||||
| --------- | ---- | ------ | ----------- | ------- | --------- |
|
||||
|
||||
## Retrieve current permission settings
|
||||
|
||||
#### Method
|
||||
|
||||
| URI | Protocol | Method | Authentication |
|
||||
| --- | -------- | ------ | -------------- |
|
||||
| `/permissions/permissions/{team}` | HTTP/S | GET | Client ID, Session ID |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Method | Description | Default | Required? |
|
||||
| --------- | ---- | ------ | ----------- | ------- | --------- |
|
||||
| scope | string | GET | Permissions scope | N/A | YES |
|
||||
| resource | string | GET | Permissions resource | N/A | YES |
|
||||
| team | string | PATH | Team ID | N/A | YES |
|
||||
|
||||
## Update permission settings
|
||||
|
||||
#### Method
|
||||
|
||||
| URI | Protocol | Method | Authentication |
|
||||
| --- | -------- | ------ | -------------- |
|
||||
| `/permissions/permissions/{team}` | HTTP/S | POST | Client ID, Session ID |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Method | Description | Default | Required? |
|
||||
| --------- | ---- | ------ | ----------- | ------- | --------- |
|
||||
| team | string | PATH | Team ID | N/A | YES |
|
||||
| permissions | []rbac.Permission | POST | List of permissions to set | N/A | YES |
|
||||
|
||||
|
||||
|
||||
|
||||
# Search entry point
|
||||
|
||||
## Search for messages
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package handlers
|
||||
|
||||
/*
|
||||
Hello! This file is auto-generated from `docs/src/spec.json`.
|
||||
|
||||
For development:
|
||||
In order to update the generated files, edit this file under the location,
|
||||
add your struct fields, imports, API definitions and whatever you want, and:
|
||||
|
||||
1. run [spec](https://github.com/titpetric/spec) in the same folder,
|
||||
2. run `./_gen.php` in this folder.
|
||||
|
||||
You may edit `permissions.go`, `permissions.util.go` or `permissions_test.go` to
|
||||
implement your API calls, helper functions and tests. The file `permissions.go`
|
||||
is only generated the first time, and will not be overwritten if it exists.
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/go-chi/chi"
|
||||
"net/http"
|
||||
|
||||
"github.com/titpetric/factory/resputil"
|
||||
|
||||
"github.com/crusttech/crust/sam/rest/request"
|
||||
)
|
||||
|
||||
// Internal API interface
|
||||
type PermissionsAPI interface {
|
||||
List(context.Context, *request.PermissionsList) (interface{}, error)
|
||||
GetTeam(context.Context, *request.PermissionsGetTeam) (interface{}, error)
|
||||
SetTeam(context.Context, *request.PermissionsSetTeam) (interface{}, error)
|
||||
}
|
||||
|
||||
// HTTP API interface
|
||||
type Permissions struct {
|
||||
List func(http.ResponseWriter, *http.Request)
|
||||
GetTeam func(http.ResponseWriter, *http.Request)
|
||||
SetTeam func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
func NewPermissions(ph PermissionsAPI) *Permissions {
|
||||
return &Permissions{
|
||||
List: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewPermissionsList()
|
||||
resputil.JSON(w, params.Fill(r), func() (interface{}, error) {
|
||||
return ph.List(r.Context(), params)
|
||||
})
|
||||
},
|
||||
GetTeam: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewPermissionsGetTeam()
|
||||
resputil.JSON(w, params.Fill(r), func() (interface{}, error) {
|
||||
return ph.GetTeam(r.Context(), params)
|
||||
})
|
||||
},
|
||||
SetTeam: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewPermissionsSetTeam()
|
||||
resputil.JSON(w, params.Fill(r), func() (interface{}, error) {
|
||||
return ph.SetTeam(r.Context(), params)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (ph *Permissions) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(middlewares...)
|
||||
r.Route("/permissions", func(r chi.Router) {
|
||||
r.Get("/permissions", ph.List)
|
||||
r.Get("/permissions/{team}", ph.GetTeam)
|
||||
r.Post("/permissions/{team}", ph.SetTeam)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/crusttech/crust/sam/rest/request"
|
||||
"github.com/crusttech/crust/sam/service"
|
||||
_ "github.com/crusttech/crust/sam/types"
|
||||
)
|
||||
|
||||
type Permissions struct {
|
||||
svc struct {
|
||||
perms service.PermissionsService
|
||||
}
|
||||
}
|
||||
|
||||
func (Permissions) New() *Permissions {
|
||||
ctrl := &Permissions{}
|
||||
ctrl.svc.perms = service.DefaultPermissions
|
||||
return ctrl
|
||||
}
|
||||
|
||||
func (ctrl *Permissions) List(ctx context.Context, r *request.PermissionsList) (interface{}, error) {
|
||||
return ctrl.svc.perms.List()
|
||||
}
|
||||
|
||||
func (ctrl *Permissions) GetTeam(ctx context.Context, r *request.PermissionsGetTeam) (interface{}, error) {
|
||||
return ctrl.svc.perms.Get(r.Team, r.Scope, r.Resource)
|
||||
}
|
||||
|
||||
func (ctrl *Permissions) SetTeam(ctx context.Context, r *request.PermissionsSetTeam) (interface{}, error) {
|
||||
return ctrl.svc.perms.Set(r.Team, r.Permissions)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/crusttech/crust/internal/rbac"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"github.com/pkg/errors"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
var _ = chi.URLParam
|
||||
var _ = types.JSONText{}
|
||||
var _ = multipart.FileHeader{}
|
||||
var _ = rbac.Operation{}
|
||||
|
||||
// Attachment original request parameters
|
||||
type AttachmentOriginal struct {
|
||||
|
||||
@@ -17,6 +17,7 @@ package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/crusttech/crust/internal/rbac"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"github.com/pkg/errors"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
var _ = chi.URLParam
|
||||
var _ = types.JSONText{}
|
||||
var _ = multipart.FileHeader{}
|
||||
var _ = rbac.Operation{}
|
||||
|
||||
// Channel list request parameters
|
||||
type ChannelList struct {
|
||||
|
||||
@@ -17,6 +17,7 @@ package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/crusttech/crust/internal/rbac"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"github.com/pkg/errors"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
var _ = chi.URLParam
|
||||
var _ = types.JSONText{}
|
||||
var _ = multipart.FileHeader{}
|
||||
var _ = rbac.Operation{}
|
||||
|
||||
// Message create request parameters
|
||||
type MessageCreate struct {
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
package request
|
||||
|
||||
/*
|
||||
Hello! This file is auto-generated from `docs/src/spec.json`.
|
||||
|
||||
For development:
|
||||
In order to update the generated files, edit this file under the location,
|
||||
add your struct fields, imports, API definitions and whatever you want, and:
|
||||
|
||||
1. run [spec](https://github.com/titpetric/spec) in the same folder,
|
||||
2. run `./_gen.php` in this folder.
|
||||
|
||||
You may edit `permissions.go`, `permissions.util.go` or `permissions_test.go` to
|
||||
implement your API calls, helper functions and tests. The file `permissions.go`
|
||||
is only generated the first time, and will not be overwritten if it exists.
|
||||
*/
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/crusttech/crust/internal/rbac"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = chi.URLParam
|
||||
var _ = types.JSONText{}
|
||||
var _ = multipart.FileHeader{}
|
||||
var _ = rbac.Operation{}
|
||||
|
||||
// Permissions list request parameters
|
||||
type PermissionsList struct {
|
||||
}
|
||||
|
||||
func NewPermissionsList() *PermissionsList {
|
||||
return &PermissionsList{}
|
||||
}
|
||||
|
||||
func (p *PermissionsList) Fill(r *http.Request) (err error) {
|
||||
if strings.ToLower(r.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(r.Body).Decode(p)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return errors.Wrap(err, "error parsing http request body")
|
||||
}
|
||||
}
|
||||
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
get := map[string]string{}
|
||||
post := map[string]string{}
|
||||
urlQuery := r.URL.Query()
|
||||
for name, param := range urlQuery {
|
||||
get[name] = string(param[0])
|
||||
}
|
||||
postVars := r.Form
|
||||
for name, param := range postVars {
|
||||
post[name] = string(param[0])
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ RequestFiller = NewPermissionsList()
|
||||
|
||||
// Permissions getTeam request parameters
|
||||
type PermissionsGetTeam struct {
|
||||
Scope string
|
||||
Resource string
|
||||
Team string
|
||||
}
|
||||
|
||||
func NewPermissionsGetTeam() *PermissionsGetTeam {
|
||||
return &PermissionsGetTeam{}
|
||||
}
|
||||
|
||||
func (p *PermissionsGetTeam) Fill(r *http.Request) (err error) {
|
||||
if strings.ToLower(r.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(r.Body).Decode(p)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return errors.Wrap(err, "error parsing http request body")
|
||||
}
|
||||
}
|
||||
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
get := map[string]string{}
|
||||
post := map[string]string{}
|
||||
urlQuery := r.URL.Query()
|
||||
for name, param := range urlQuery {
|
||||
get[name] = string(param[0])
|
||||
}
|
||||
postVars := r.Form
|
||||
for name, param := range postVars {
|
||||
post[name] = string(param[0])
|
||||
}
|
||||
|
||||
if val, ok := get["scope"]; ok {
|
||||
|
||||
p.Scope = val
|
||||
}
|
||||
if val, ok := get["resource"]; ok {
|
||||
|
||||
p.Resource = val
|
||||
}
|
||||
p.Team = chi.URLParam(r, "team")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ RequestFiller = NewPermissionsGetTeam()
|
||||
|
||||
// Permissions setTeam request parameters
|
||||
type PermissionsSetTeam struct {
|
||||
Team string
|
||||
Permissions []rbac.Permission
|
||||
}
|
||||
|
||||
func NewPermissionsSetTeam() *PermissionsSetTeam {
|
||||
return &PermissionsSetTeam{}
|
||||
}
|
||||
|
||||
func (p *PermissionsSetTeam) Fill(r *http.Request) (err error) {
|
||||
if strings.ToLower(r.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(r.Body).Decode(p)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return errors.Wrap(err, "error parsing http request body")
|
||||
}
|
||||
}
|
||||
|
||||
if err = r.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
get := map[string]string{}
|
||||
post := map[string]string{}
|
||||
urlQuery := r.URL.Query()
|
||||
for name, param := range urlQuery {
|
||||
get[name] = string(param[0])
|
||||
}
|
||||
postVars := r.Form
|
||||
for name, param := range postVars {
|
||||
post[name] = string(param[0])
|
||||
}
|
||||
|
||||
p.Team = chi.URLParam(r, "team")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ RequestFiller = NewPermissionsSetTeam()
|
||||
@@ -17,6 +17,7 @@ package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/crusttech/crust/internal/rbac"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
"github.com/pkg/errors"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
var _ = chi.URLParam
|
||||
var _ = types.JSONText{}
|
||||
var _ = multipart.FileHeader{}
|
||||
var _ = rbac.Operation{}
|
||||
|
||||
// Search messages request parameters
|
||||
type SearchMessages struct {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/crusttech/crust/internal/rbac"
|
||||
"github.com/crusttech/crust/sam/repository"
|
||||
)
|
||||
|
||||
type (
|
||||
permissions struct {
|
||||
db db
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
PermissionsService interface {
|
||||
With(ctx context.Context) PermissionsService
|
||||
|
||||
List() (interface{}, error)
|
||||
Get(team string, scope string, resource string) (interface{}, error)
|
||||
Set(team string, permissions []rbac.Permission) (interface{}, error)
|
||||
}
|
||||
)
|
||||
|
||||
func Permissions() PermissionsService {
|
||||
return (&permissions{}).With(context.Background())
|
||||
}
|
||||
|
||||
func (svc *permissions) With(ctx context.Context) PermissionsService {
|
||||
db := repository.DB(ctx)
|
||||
return &permissions{
|
||||
db: db,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *permissions) List() (interface{}, error) {
|
||||
return nil, errors.New("service.permissions.list: not implemented")
|
||||
}
|
||||
|
||||
func (p *permissions) Get(team string, scope string, resource string) (interface{}, error) {
|
||||
return nil, errors.New("service.permissions.get: not implemented")
|
||||
}
|
||||
|
||||
func (p *permissions) Set(team string, permissions []rbac.Permission) (interface{}, error) {
|
||||
return nil, errors.New("service.permissions.set: not implemented")
|
||||
}
|
||||
@@ -15,12 +15,13 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
o sync.Once
|
||||
DefaultAttachment AttachmentService
|
||||
DefaultChannel ChannelService
|
||||
DefaultMessage MessageService
|
||||
DefaultPubSub *pubSub
|
||||
DefaultEvent EventService
|
||||
o sync.Once
|
||||
DefaultAttachment AttachmentService
|
||||
DefaultChannel ChannelService
|
||||
DefaultMessage MessageService
|
||||
DefaultPermissions PermissionsService
|
||||
DefaultPubSub *pubSub
|
||||
DefaultEvent EventService
|
||||
)
|
||||
|
||||
func Init() {
|
||||
@@ -33,6 +34,7 @@ func Init() {
|
||||
DefaultEvent = Event()
|
||||
DefaultAttachment = Attachment(fs)
|
||||
DefaultMessage = Message()
|
||||
DefaultPermissions = Permissions()
|
||||
DefaultChannel = Channel()
|
||||
DefaultPubSub = PubSub()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user