mirror of
https://github.com/openziti/zrok.git
synced 2024-11-27 02:23:23 +01:00
elaborating the grants handler (#744)
This commit is contained in:
parent
a37009249a
commit
e5aac2358b
@ -2,8 +2,10 @@ package controller
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/openziti/zrok/controller/zrokEdgeSdk"
|
||||
"github.com/openziti/zrok/rest_model_zrok"
|
||||
"github.com/openziti/zrok/rest_server_zrok/operations/admin"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -18,5 +20,67 @@ func (h *grantsHandler) Handle(params admin.GrantsParams, principal *rest_model_
|
||||
logrus.Errorf("invalid admin principal")
|
||||
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()
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/openziti/edge-api/rest_model"
|
||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||
"github.com/sirupsen/logrus"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -55,6 +56,41 @@ func CreateConfig(cfgTypeZId, envZId, shrToken string, options *FrontendOptions,
|
||||
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 {
|
||||
filter := fmt.Sprintf("tags.zrokShareToken=\"%v\"", shrToken)
|
||||
limit := int64(0)
|
||||
|
@ -34,6 +34,12 @@ func (o *GrantsReader) ReadResponse(response runtime.ClientResponse, consumer ru
|
||||
return nil, err
|
||||
}
|
||||
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:
|
||||
result := NewGrantsInternalServerError()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
@ -157,6 +163,62 @@ func (o *GrantsUnauthorized) readResponse(response runtime.ClientResponse, consu
|
||||
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
|
||||
func NewGrantsInternalServerError() *GrantsInternalServerError {
|
||||
return &GrantsInternalServerError{}
|
||||
|
@ -557,6 +557,9 @@ func init() {
|
||||
"401": {
|
||||
"description": "unauthorized"
|
||||
},
|
||||
"404": {
|
||||
"description": "not found"
|
||||
},
|
||||
"500": {
|
||||
"description": "internal server error"
|
||||
}
|
||||
@ -2404,6 +2407,9 @@ func init() {
|
||||
"401": {
|
||||
"description": "unauthorized"
|
||||
},
|
||||
"404": {
|
||||
"description": "not found"
|
||||
},
|
||||
"500": {
|
||||
"description": "internal server error"
|
||||
}
|
||||
|
@ -61,6 +61,31 @@ func (o *GrantsUnauthorized) WriteResponse(rw http.ResponseWriter, producer runt
|
||||
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
|
||||
const GrantsInternalServerErrorCode int = 500
|
||||
|
||||
|
@ -2,6 +2,8 @@ package sdk
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const ZrokProxyConfig = "zrok.proxy.v1"
|
||||
@ -13,21 +15,133 @@ type FrontendConfig struct {
|
||||
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 {
|
||||
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 {
|
||||
Username string `json:"username"`
|
||||
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 {
|
||||
Provider string `json:"provider"`
|
||||
EmailDomains []string `json:"email_domains"`
|
||||
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) {
|
||||
switch authScheme {
|
||||
case string(None):
|
||||
|
@ -326,6 +326,8 @@ paths:
|
||||
description: ok
|
||||
401:
|
||||
description: unauthorized
|
||||
404:
|
||||
description: not found
|
||||
500:
|
||||
description: internal server error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user