add(sam): spec and scaffold of permissions api

This commit is contained in:
Tit Petric
2018-12-04 14:38:31 +01:00
parent 71fb80945a
commit d9606440b7
12 changed files with 543 additions and 6 deletions
+73
View File
@@ -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"
}
]
}
}
]
}
]
+76
View File
@@ -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"
}
]
}
}
]
}
+49
View File
@@ -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
+77
View File
@@ -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)
})
})
}
+33
View File
@@ -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)
}
+2
View File
@@ -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 {
+2
View File
@@ -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 {
+2
View File
@@ -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 {
+170
View File
@@ -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()
+2
View File
@@ -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 {
+49
View File
@@ -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")
}
+8 -6
View File
@@ -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()
})