mirror of
https://github.com/openziti/zrok.git
synced 2024-11-23 08:33:52 +01:00
elaborating the grants handler (#744)
This commit is contained in:
parent
a37009249a
commit
e5aac2358b
@ -2,8 +2,10 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/openziti/zrok/controller/zrokEdgeSdk"
|
||||||
"github.com/openziti/zrok/rest_model_zrok"
|
"github.com/openziti/zrok/rest_model_zrok"
|
||||||
"github.com/openziti/zrok/rest_server_zrok/operations/admin"
|
"github.com/openziti/zrok/rest_server_zrok/operations/admin"
|
||||||
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,5 +20,67 @@ func (h *grantsHandler) Handle(params admin.GrantsParams, principal *rest_model_
|
|||||||
logrus.Errorf("invalid admin principal")
|
logrus.Errorf("invalid admin principal")
|
||||||
return admin.NewGrantsUnauthorized()
|
return admin.NewGrantsUnauthorized()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
edge, err := zrokEdgeSdk.Client(cfg.Ziti)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error connecting to ziti: %v", err)
|
||||||
|
return admin.NewGrantsInternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
trx, err := str.Begin()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error starting transaction: %v", err)
|
||||||
|
return admin.NewGrantsInternalServerError()
|
||||||
|
}
|
||||||
|
defer func() { _ = trx.Rollback() }()
|
||||||
|
|
||||||
|
acct, err := str.FindAccountWithEmail(params.Body.Email, trx)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error finding account with email '%v': %v", params.Body.Email, err)
|
||||||
|
return admin.NewGrantsNotFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
acctSkipInterstitial, err := str.IsAccountGrantedSkipInterstitial(acct.Id, trx)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error checking account '%v' granted skip interstitial: %v", acct.Email, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
envs, err := str.FindEnvironmentsForAccount(acct.Id, trx)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error finding environments for '%v': %v", acct.Email, err)
|
||||||
|
return admin.NewGrantsInternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, env := range envs {
|
||||||
|
shrs, err := str.FindSharesForEnvironment(env.Id, trx)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error finding shares for '%v': %v", acct.Email, err)
|
||||||
|
return admin.NewGrantsInternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, shr := range shrs {
|
||||||
|
if shr.ShareMode == string(sdk.PublicShareMode) && shr.BackendMode != string(sdk.DriveBackendMode) {
|
||||||
|
cfgZId, shrCfg, err := zrokEdgeSdk.GetConfig(shr.Token, edge)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error getting config for share '%v': %v", shr.Token, err)
|
||||||
|
return admin.NewGrantsInternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
if shrCfg.Interstitial != !acctSkipInterstitial {
|
||||||
|
logrus.Infof("updating config for '%v'", shr.Token)
|
||||||
|
err := zrokEdgeSdk.UpdateConfig(cfgZId, shrCfg, edge)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("error updating config for '%v': %v", shr.Token, err)
|
||||||
|
return admin.NewGrantsInternalServerError()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logrus.Infof("skipping config update for '%v'", shr.Token)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logrus.Debugf("skipping share mode %v, backend mode %v", shr.ShareMode, shr.BackendMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return admin.NewGrantsOK()
|
return admin.NewGrantsOK()
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/openziti/edge-api/rest_model"
|
"github.com/openziti/edge-api/rest_model"
|
||||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -55,6 +56,41 @@ func CreateConfig(cfgTypeZId, envZId, shrToken string, options *FrontendOptions,
|
|||||||
return cfgResp.Payload.Data.ID, nil
|
return cfgResp.Payload.Data.ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetConfig(shrToken string, edge *rest_management_api_client.ZitiEdgeManagement) (string, *sdk.FrontendConfig, error) {
|
||||||
|
filter := fmt.Sprintf("tags.zrokShareToken=\"%v\"", shrToken)
|
||||||
|
limit := int64(0)
|
||||||
|
offset := int64(0)
|
||||||
|
listReq := &config.ListConfigsParams{
|
||||||
|
Filter: &filter,
|
||||||
|
Limit: &limit,
|
||||||
|
Offset: &offset,
|
||||||
|
Context: context.Background(),
|
||||||
|
}
|
||||||
|
listReq.SetTimeout(30 * time.Second)
|
||||||
|
listResp, err := edge.Config.ListConfigs(listReq, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
if len(listResp.Payload.Data) != 1 {
|
||||||
|
return "", nil, fmt.Errorf("expected 1 configuration, found %v", len(listResp.Payload.Data))
|
||||||
|
}
|
||||||
|
if listResp.Payload.Data[0].ConfigType.Name != sdk.ZrokProxyConfig {
|
||||||
|
return "", nil, fmt.Errorf("expected '%v', found '%v'", sdk.ZrokProxyConfig, listResp.Payload.Data[0].ConfigType.Name)
|
||||||
|
}
|
||||||
|
if v, ok := listResp.Payload.Data[0].Data.(map[string]interface{}); ok {
|
||||||
|
fec, err := sdk.FrontendConfigFromMap(v)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return *listResp.Payload.Data[0].ID, fec, nil
|
||||||
|
}
|
||||||
|
return "", nil, fmt.Errorf("unknown data type '%v' unmarshaling config for '%v'", reflect.TypeOf(listResp.Payload.Data[0].Data), shrToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateConfig(cfgZId string, cfg *sdk.FrontendConfig, edge *rest_management_api_client.ZitiEdgeManagement) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteConfig(envZId, shrToken string, edge *rest_management_api_client.ZitiEdgeManagement) error {
|
func DeleteConfig(envZId, shrToken string, edge *rest_management_api_client.ZitiEdgeManagement) error {
|
||||||
filter := fmt.Sprintf("tags.zrokShareToken=\"%v\"", shrToken)
|
filter := fmt.Sprintf("tags.zrokShareToken=\"%v\"", shrToken)
|
||||||
limit := int64(0)
|
limit := int64(0)
|
||||||
|
@ -34,6 +34,12 @@ func (o *GrantsReader) ReadResponse(response runtime.ClientResponse, consumer ru
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, result
|
return nil, result
|
||||||
|
case 404:
|
||||||
|
result := NewGrantsNotFound()
|
||||||
|
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, result
|
||||||
case 500:
|
case 500:
|
||||||
result := NewGrantsInternalServerError()
|
result := NewGrantsInternalServerError()
|
||||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||||
@ -157,6 +163,62 @@ func (o *GrantsUnauthorized) readResponse(response runtime.ClientResponse, consu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGrantsNotFound creates a GrantsNotFound with default headers values
|
||||||
|
func NewGrantsNotFound() *GrantsNotFound {
|
||||||
|
return &GrantsNotFound{}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GrantsNotFound describes a response with status code 404, with default header values.
|
||||||
|
|
||||||
|
not found
|
||||||
|
*/
|
||||||
|
type GrantsNotFound struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSuccess returns true when this grants not found response has a 2xx status code
|
||||||
|
func (o *GrantsNotFound) IsSuccess() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRedirect returns true when this grants not found response has a 3xx status code
|
||||||
|
func (o *GrantsNotFound) IsRedirect() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsClientError returns true when this grants not found response has a 4xx status code
|
||||||
|
func (o *GrantsNotFound) IsClientError() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsServerError returns true when this grants not found response has a 5xx status code
|
||||||
|
func (o *GrantsNotFound) IsServerError() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCode returns true when this grants not found response a status code equal to that given
|
||||||
|
func (o *GrantsNotFound) IsCode(code int) bool {
|
||||||
|
return code == 404
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code gets the status code for the grants not found response
|
||||||
|
func (o *GrantsNotFound) Code() int {
|
||||||
|
return 404
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GrantsNotFound) Error() string {
|
||||||
|
return fmt.Sprintf("[POST /grants][%d] grantsNotFound ", 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GrantsNotFound) String() string {
|
||||||
|
return fmt.Sprintf("[POST /grants][%d] grantsNotFound ", 404)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GrantsNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewGrantsInternalServerError creates a GrantsInternalServerError with default headers values
|
// NewGrantsInternalServerError creates a GrantsInternalServerError with default headers values
|
||||||
func NewGrantsInternalServerError() *GrantsInternalServerError {
|
func NewGrantsInternalServerError() *GrantsInternalServerError {
|
||||||
return &GrantsInternalServerError{}
|
return &GrantsInternalServerError{}
|
||||||
|
@ -557,6 +557,9 @@ func init() {
|
|||||||
"401": {
|
"401": {
|
||||||
"description": "unauthorized"
|
"description": "unauthorized"
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "not found"
|
||||||
|
},
|
||||||
"500": {
|
"500": {
|
||||||
"description": "internal server error"
|
"description": "internal server error"
|
||||||
}
|
}
|
||||||
@ -2404,6 +2407,9 @@ func init() {
|
|||||||
"401": {
|
"401": {
|
||||||
"description": "unauthorized"
|
"description": "unauthorized"
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "not found"
|
||||||
|
},
|
||||||
"500": {
|
"500": {
|
||||||
"description": "internal server error"
|
"description": "internal server error"
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,31 @@ func (o *GrantsUnauthorized) WriteResponse(rw http.ResponseWriter, producer runt
|
|||||||
rw.WriteHeader(401)
|
rw.WriteHeader(401)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GrantsNotFoundCode is the HTTP code returned for type GrantsNotFound
|
||||||
|
const GrantsNotFoundCode int = 404
|
||||||
|
|
||||||
|
/*
|
||||||
|
GrantsNotFound not found
|
||||||
|
|
||||||
|
swagger:response grantsNotFound
|
||||||
|
*/
|
||||||
|
type GrantsNotFound struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGrantsNotFound creates GrantsNotFound with default headers values
|
||||||
|
func NewGrantsNotFound() *GrantsNotFound {
|
||||||
|
|
||||||
|
return &GrantsNotFound{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GrantsNotFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||||
|
|
||||||
|
rw.WriteHeader(404)
|
||||||
|
}
|
||||||
|
|
||||||
// GrantsInternalServerErrorCode is the HTTP code returned for type GrantsInternalServerError
|
// GrantsInternalServerErrorCode is the HTTP code returned for type GrantsInternalServerError
|
||||||
const GrantsInternalServerErrorCode int = 500
|
const GrantsInternalServerErrorCode int = 500
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package sdk
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ZrokProxyConfig = "zrok.proxy.v1"
|
const ZrokProxyConfig = "zrok.proxy.v1"
|
||||||
@ -13,21 +15,133 @@ type FrontendConfig struct {
|
|||||||
OauthAuth *OauthConfig `json:"oauth"`
|
OauthAuth *OauthConfig `json:"oauth"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FrontendConfigFromMap(m map[string]interface{}) (*FrontendConfig, error) {
|
||||||
|
logrus.Info(m)
|
||||||
|
out := &FrontendConfig{}
|
||||||
|
if v, found := m["interstitial"]; found {
|
||||||
|
out.Interstitial = v.(bool)
|
||||||
|
}
|
||||||
|
if v, found := m["auth_scheme"]; found {
|
||||||
|
if vStr, ok := v.(string); ok {
|
||||||
|
out.AuthScheme = AuthScheme(vStr)
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := m["basic_auth"]; found && v != nil {
|
||||||
|
if subMap, ok := v.(map[string]interface{}); ok {
|
||||||
|
ba, err := BasicAuthConfigFromMap(subMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out.BasicAuth = ba
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := m["oauth"]; found && v != nil {
|
||||||
|
if subMap, ok := v.(map[string]interface{}); ok {
|
||||||
|
o, err := OauthConfigFromMap(subMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out.OauthAuth = o
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type BasicAuthConfig struct {
|
type BasicAuthConfig struct {
|
||||||
Users []*AuthUserConfig `json:"users"`
|
Users []*AuthUserConfig `json:"users"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BasicAuthConfigFromMap(m map[string]interface{}) (*BasicAuthConfig, error) {
|
||||||
|
out := &BasicAuthConfig{}
|
||||||
|
if v, found := m["basic_auth"]; found {
|
||||||
|
if vArr, ok := v.([]interface{}); ok {
|
||||||
|
for _, vV := range vArr {
|
||||||
|
if v, ok := vV.(map[string]interface{}); ok {
|
||||||
|
if auc, err := AuthUserConfigFromMap(v); err == nil {
|
||||||
|
out.Users = append(out.Users, auc)
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
type AuthUserConfig struct {
|
type AuthUserConfig struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AuthUserConfigFromMap(m map[string]interface{}) (*AuthUserConfig, error) {
|
||||||
|
auc := &AuthUserConfig{}
|
||||||
|
if v, found := m["username"]; found {
|
||||||
|
if vStr, ok := v.(string); ok {
|
||||||
|
auc.Username = vStr
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := m["password"]; found {
|
||||||
|
if vStr, ok := v.(string); ok {
|
||||||
|
auc.Password = vStr
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return auc, nil
|
||||||
|
}
|
||||||
|
|
||||||
type OauthConfig struct {
|
type OauthConfig struct {
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
EmailDomains []string `json:"email_domains"`
|
EmailDomains []string `json:"email_domains"`
|
||||||
AuthorizationCheckInterval string `json:"authorization_check_interval"`
|
AuthorizationCheckInterval string `json:"authorization_check_interval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func OauthConfigFromMap(m map[string]interface{}) (*OauthConfig, error) {
|
||||||
|
oac := &OauthConfig{}
|
||||||
|
if v, found := m["provider"]; found {
|
||||||
|
if vStr, ok := v.(string); ok {
|
||||||
|
oac.Provider = vStr
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := m["email_domains"]; found {
|
||||||
|
if vArr, ok := v.([]interface{}); ok {
|
||||||
|
for _, vV := range vArr {
|
||||||
|
if vStr, ok := vV.(string); ok {
|
||||||
|
oac.EmailDomains = append(oac.EmailDomains, vStr)
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(vV))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := m["authorization_check_interval"]; found {
|
||||||
|
if vStr, ok := v.(string); ok {
|
||||||
|
oac.AuthorizationCheckInterval = vStr
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("unexpected type '%v'", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oac, nil
|
||||||
|
}
|
||||||
|
|
||||||
func ParseAuthScheme(authScheme string) (AuthScheme, error) {
|
func ParseAuthScheme(authScheme string) (AuthScheme, error) {
|
||||||
switch authScheme {
|
switch authScheme {
|
||||||
case string(None):
|
case string(None):
|
||||||
|
@ -326,6 +326,8 @@ paths:
|
|||||||
description: ok
|
description: ok
|
||||||
401:
|
401:
|
||||||
description: unauthorized
|
description: unauthorized
|
||||||
|
404:
|
||||||
|
description: not found
|
||||||
500:
|
500:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user