mirror of
https://github.com/openziti/zrok.git
synced 2024-11-22 16:13:47 +01:00
Merge pull request #573 from openziti/permission_model
Permission Model: Phase 1 (#432)
This commit is contained in:
commit
f1c9f11e4d
@ -2,6 +2,8 @@
|
||||
|
||||
## v0.4.26
|
||||
|
||||
FEATURE: New _permission modes_ available for shares. _Open permission mode_ retains the behavior of previous zrok releases and is the default setting. _Closed permission mode_ (`--closed`) only allows a share to be accessed (`zrok access`) by users who have been granted access with the `--access-grant` flag. See the documentation at (https://docs.zrok.io/docs/guides/permission-modes/) (https://github.com/openziti/zrok/issues/432)
|
||||
|
||||
CHANGE: The target for a `socks` share is automatically set to `socks` to improve web console display.
|
||||
|
||||
CHANGE: Enhancements to the look and feel of the account actions tab in the web console. Textual improvements.
|
||||
|
@ -26,6 +26,7 @@ func init() {
|
||||
testCmd.AddCommand(loopCmd)
|
||||
rootCmd.AddCommand(adminCmd)
|
||||
rootCmd.AddCommand(configCmd)
|
||||
rootCmd.AddCommand(modifyCmd)
|
||||
rootCmd.AddCommand(shareCmd)
|
||||
rootCmd.AddCommand(testCmd)
|
||||
transport.AddAddressParser(tcp.AddressParser{})
|
||||
@ -85,6 +86,12 @@ var loopCmd = &cobra.Command{
|
||||
Short: "Loopback testing utilities",
|
||||
}
|
||||
|
||||
var modifyCmd = &cobra.Command{
|
||||
Use: "modify",
|
||||
Aliases: []string{"mod"},
|
||||
Short: "Modify resources",
|
||||
}
|
||||
|
||||
var shareCmd = &cobra.Command{
|
||||
Use: "share",
|
||||
Short: "Create backend access for shares",
|
||||
|
75
cmd/zrok/modifyShare.go
Normal file
75
cmd/zrok/modifyShare.go
Normal file
@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/openziti/zrok/environment"
|
||||
"github.com/openziti/zrok/rest_client_zrok/share"
|
||||
"github.com/openziti/zrok/rest_model_zrok"
|
||||
"github.com/openziti/zrok/tui"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
modifyCmd.AddCommand(newModifyShareCommand().cmd)
|
||||
}
|
||||
|
||||
type modifyShareCommand struct {
|
||||
addAccessGrants []string
|
||||
removeAccessGrants []string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func newModifyShareCommand() *modifyShareCommand {
|
||||
cmd := &cobra.Command{
|
||||
Use: "share <shareToken>",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Short: "Modify a share",
|
||||
}
|
||||
command := &modifyShareCommand{cmd: cmd}
|
||||
cmd.Flags().StringArrayVar(&command.addAccessGrants, "add-access-grant", []string{}, "Add an access grant (email address)")
|
||||
cmd.Flags().StringArrayVar(&command.removeAccessGrants, "remove-access-grant", []string{}, "Remove an access grant (email address)")
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
|
||||
func (cmd *modifyShareCommand) run(_ *cobra.Command, args []string) {
|
||||
shrToken := args[0]
|
||||
|
||||
root, err := environment.LoadRoot()
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("error loading environment", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !root.IsEnabled() {
|
||||
tui.Error("unable to load environment; did you 'zrok enable'?", nil)
|
||||
}
|
||||
|
||||
zrok, err := root.Client()
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to create zrok client", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
auth := httptransport.APIKeyAuth("X-TOKEN", "header", root.Environment().Token)
|
||||
|
||||
if len(cmd.addAccessGrants) > 0 || len(cmd.removeAccessGrants) > 0 {
|
||||
req := share.NewUpdateShareParams()
|
||||
req.Body = &rest_model_zrok.UpdateShareRequest{
|
||||
ShrToken: shrToken,
|
||||
AddAccessGrants: cmd.addAccessGrants,
|
||||
RemoveAccessGrants: cmd.removeAccessGrants,
|
||||
}
|
||||
if _, err := zrok.Share.UpdateShare(req, auth); err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to update share", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("updated")
|
||||
}
|
||||
}
|
@ -26,6 +26,8 @@ type reserveCommand struct {
|
||||
oauthProvider string
|
||||
oauthEmailAddressPatterns []string
|
||||
oauthCheckInterval time.Duration
|
||||
closed bool
|
||||
accessGrants []string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
@ -45,6 +47,8 @@ func newReserveCommand() *reserveCommand {
|
||||
cmd.Flags().StringArrayVar(&command.oauthEmailAddressPatterns, "oauth-email-address-patterns", []string{}, "Allow only these email domains to authenticate via OAuth")
|
||||
cmd.Flags().DurationVar(&command.oauthCheckInterval, "oauth-check-interval", 3*time.Hour, "Maximum lifetime for OAuth authentication; reauthenticate after expiry")
|
||||
cmd.MarkFlagsMutuallyExclusive("basic-auth", "oauth-provider")
|
||||
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)")
|
||||
cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)")
|
||||
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
@ -142,6 +146,10 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) {
|
||||
req.OauthEmailAddressPatterns = cmd.oauthEmailAddressPatterns
|
||||
req.OauthAuthorizationCheckInterval = cmd.oauthCheckInterval
|
||||
}
|
||||
if cmd.closed {
|
||||
req.PermissionMode = sdk.ClosedPermissionMode
|
||||
req.AccessGrants = cmd.accessGrants
|
||||
}
|
||||
shr, err := sdk.CreateShare(env, req)
|
||||
if err != nil {
|
||||
tui.Error("unable to create share", err)
|
||||
|
@ -25,11 +25,13 @@ func init() {
|
||||
}
|
||||
|
||||
type sharePrivateCommand struct {
|
||||
basicAuth []string
|
||||
backendMode string
|
||||
headless bool
|
||||
insecure bool
|
||||
cmd *cobra.Command
|
||||
basicAuth []string
|
||||
backendMode string
|
||||
headless bool
|
||||
insecure bool
|
||||
closed bool
|
||||
accessGrants []string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func newSharePrivateCommand() *sharePrivateCommand {
|
||||
@ -43,6 +45,8 @@ func newSharePrivateCommand() *sharePrivateCommand {
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, tcpTunnel, udpTunnel, caddy, drive, socks}")
|
||||
cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless")
|
||||
cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for <target>")
|
||||
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)")
|
||||
cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)")
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
@ -131,6 +135,10 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
BasicAuth: cmd.basicAuth,
|
||||
Target: target,
|
||||
}
|
||||
if cmd.closed {
|
||||
req.PermissionMode = sdk.ClosedPermissionMode
|
||||
req.AccessGrants = cmd.accessGrants
|
||||
}
|
||||
shr, err := sdk.CreateShare(root, req)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
|
@ -33,6 +33,8 @@ type sharePublicCommand struct {
|
||||
oauthProvider string
|
||||
oauthEmailAddressPatterns []string
|
||||
oauthCheckInterval time.Duration
|
||||
closed bool
|
||||
accessGrants []string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
@ -47,6 +49,8 @@ func newSharePublicCommand() *sharePublicCommand {
|
||||
cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, caddy, drive}")
|
||||
cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless")
|
||||
cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for <target>")
|
||||
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)")
|
||||
cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)")
|
||||
|
||||
cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (<username:password>,...)")
|
||||
cmd.Flags().StringVar(&command.oauthProvider, "oauth-provider", "", "Enable OAuth provider [google, github]")
|
||||
@ -113,6 +117,10 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) {
|
||||
BasicAuth: cmd.basicAuth,
|
||||
Target: target,
|
||||
}
|
||||
if cmd.closed {
|
||||
req.PermissionMode = sdk.ClosedPermissionMode
|
||||
req.AccessGrants = cmd.accessGrants
|
||||
}
|
||||
if cmd.oauthProvider != "" {
|
||||
req.OauthProvider = cmd.oauthProvider
|
||||
req.OauthEmailAddressPatterns = cmd.oauthEmailAddressPatterns
|
||||
|
@ -49,7 +49,7 @@ func (h *accessHandler) Handle(params share.AccessParams, principal *rest_model_
|
||||
shrToken := params.Body.ShrToken
|
||||
shr, err := str.FindShareWithToken(shrToken, trx)
|
||||
if err != nil {
|
||||
logrus.Errorf("error finding share")
|
||||
logrus.Errorf("error finding share with token '%v': %v", shrToken, err)
|
||||
return share.NewAccessNotFound()
|
||||
}
|
||||
if shr == nil {
|
||||
@ -57,6 +57,19 @@ func (h *accessHandler) Handle(params share.AccessParams, principal *rest_model_
|
||||
return share.NewAccessNotFound()
|
||||
}
|
||||
|
||||
if shr.PermissionMode == store.ClosedPermissionMode {
|
||||
shrEnv, err := str.GetEnvironment(shr.EnvironmentId, trx)
|
||||
if err != nil {
|
||||
logrus.Errorf("error getting environment for share '%v': %v", shrToken, err)
|
||||
return share.NewAccessInternalServerError()
|
||||
}
|
||||
|
||||
if err := h.checkAccessGrants(shr, *shrEnv.AccountId, principal, trx); err != nil {
|
||||
logrus.Errorf("closed permission mode for '%v' fails for '%v': %v", shr.Token, principal.Email, err)
|
||||
return share.NewAccessUnauthorized()
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.checkLimits(shr, trx); err != nil {
|
||||
logrus.Errorf("cannot access limited share for '%v': %v", principal.Email, err)
|
||||
return share.NewAccessNotFound()
|
||||
@ -111,3 +124,20 @@ func (h *accessHandler) checkLimits(shr *store.Share, trx *sqlx.Tx) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *accessHandler) checkAccessGrants(shr *store.Share, ownerAccountId int, principal *rest_model_zrok.Principal, trx *sqlx.Tx) error {
|
||||
if int(principal.ID) == ownerAccountId {
|
||||
logrus.Infof("accessing own share '%v' for '%v'", shr.Token, principal.Email)
|
||||
return nil
|
||||
}
|
||||
count, err := str.CheckAccessGrantForShareAndAccount(shr.Id, int(principal.ID), trx)
|
||||
if err != nil {
|
||||
logrus.Infof("error checking access grants for '%v': %v", shr.Token, err)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
logrus.Infof("found '%d' grants for '%v'", count, principal.Email)
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("access denied for '%v' accessing '%v'", principal.Email, shr.Token)
|
||||
}
|
||||
|
@ -54,6 +54,19 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
return share.NewShareUnauthorized()
|
||||
}
|
||||
|
||||
var accessGrantAcctIds []int
|
||||
if store.PermissionMode(params.Body.PermissionMode) == store.ClosedPermissionMode {
|
||||
for _, email := range params.Body.AccessGrants {
|
||||
acct, err := str.FindAccountWithEmail(email, trx)
|
||||
if err != nil {
|
||||
logrus.Errorf("unable to find account '%v' for share request from '%v'", email, principal.Email)
|
||||
return share.NewShareNotFound()
|
||||
}
|
||||
logrus.Debugf("found id '%d' for '%v'", acct.Id, acct.Email)
|
||||
accessGrantAcctIds = append(accessGrantAcctIds, acct.Id)
|
||||
}
|
||||
}
|
||||
|
||||
edge, err := zrokEdgeSdk.Client(cfg.Ziti)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
@ -134,6 +147,10 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
BackendMode: params.Body.BackendMode,
|
||||
BackendProxyEndpoint: ¶ms.Body.BackendProxyEndpoint,
|
||||
Reserved: reserved,
|
||||
PermissionMode: store.OpenPermissionMode,
|
||||
}
|
||||
if params.Body.PermissionMode != "" {
|
||||
sshr.PermissionMode = store.PermissionMode(params.Body.PermissionMode)
|
||||
}
|
||||
if len(params.Body.FrontendSelection) > 0 {
|
||||
sshr.FrontendSelection = ¶ms.Body.FrontendSelection[0]
|
||||
@ -150,6 +167,16 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr
|
||||
return share.NewShareInternalServerError()
|
||||
}
|
||||
|
||||
if sshr.PermissionMode == store.ClosedPermissionMode {
|
||||
for _, acctId := range accessGrantAcctIds {
|
||||
_, err := str.CreateAccessGrant(sid, acctId, trx)
|
||||
if err != nil {
|
||||
logrus.Errorf("error creating access grant for '%v': %v", principal.Email, err)
|
||||
return share.NewShareInternalServerError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := trx.Commit(); err != nil {
|
||||
logrus.Errorf("error committing share record: %v", err)
|
||||
return share.NewShareInternalServerError()
|
||||
|
57
controller/store/accessGrant.go
Normal file
57
controller/store/accessGrant.go
Normal file
@ -0,0 +1,57 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type AccessGrant struct {
|
||||
Model
|
||||
ShareId int
|
||||
AccountId int
|
||||
}
|
||||
|
||||
func (str *Store) CreateAccessGrant(shareId, accountId int, tx *sqlx.Tx) (int, error) {
|
||||
stmt, err := tx.Prepare("insert into access_grants (share_id, account_id) values ($1, $2) returning id")
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error preparing access_grant insert statement")
|
||||
}
|
||||
var id int
|
||||
if err := stmt.QueryRow(shareId, accountId).Scan(&id); err != nil {
|
||||
return 0, errors.Wrap(err, "error executing access_grant insert statement")
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (str *Store) CheckAccessGrantForShareAndAccount(shrId, acctId int, tx *sqlx.Tx) (int, error) {
|
||||
count := 0
|
||||
err := tx.QueryRowx("select count(0) from access_grants where share_id = $1 and account_id = $2 and not deleted", shrId, acctId).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error selecting access_grants by share_id and account_id")
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (str *Store) DeleteAccessGrantsForShare(shrId int, tx *sqlx.Tx) error {
|
||||
stmt, err := tx.Prepare("update access_grants set updated_at = current_timestamp, deleted = true where share_id = $1")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error preparing access_grants delete for shares statement")
|
||||
}
|
||||
_, err = stmt.Exec(shrId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error executing access_grants delete for shares statement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (str *Store) DeleteAccessGrantsForShareAndAccount(shrId, acctId int, tx *sqlx.Tx) error {
|
||||
stmt, err := tx.Prepare("update access_grants set updated_at = current_timestamp, deleted = true where share_id = $1 and account_id = $2")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error preparing access_grants delete for share and account statement")
|
||||
}
|
||||
_, err = stmt.Exec(shrId, acctId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error executing access_grants delete for share and account statement")
|
||||
}
|
||||
return nil
|
||||
}
|
@ -7,3 +7,10 @@ const (
|
||||
WarningAction LimitJournalAction = "warning"
|
||||
ClearAction LimitJournalAction = "clear"
|
||||
)
|
||||
|
||||
type PermissionMode string
|
||||
|
||||
const (
|
||||
OpenPermissionMode PermissionMode = "open"
|
||||
ClosedPermissionMode PermissionMode = "closed"
|
||||
)
|
||||
|
@ -16,16 +16,17 @@ type Share struct {
|
||||
FrontendEndpoint *string
|
||||
BackendProxyEndpoint *string
|
||||
Reserved bool
|
||||
PermissionMode PermissionMode
|
||||
Deleted bool
|
||||
}
|
||||
|
||||
func (str *Store) CreateShare(envId int, shr *Share, tx *sqlx.Tx) (int, error) {
|
||||
stmt, err := tx.Prepare("insert into shares (environment_id, z_id, token, share_mode, backend_mode, frontend_selection, frontend_endpoint, backend_proxy_endpoint, reserved) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) returning id")
|
||||
stmt, err := tx.Prepare("insert into shares (environment_id, z_id, token, share_mode, backend_mode, frontend_selection, frontend_endpoint, backend_proxy_endpoint, reserved, permission_mode) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) returning id")
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error preparing shares insert statement")
|
||||
}
|
||||
var id int
|
||||
if err := stmt.QueryRow(envId, shr.ZId, shr.Token, shr.ShareMode, shr.BackendMode, shr.FrontendSelection, shr.FrontendEndpoint, shr.BackendProxyEndpoint, shr.Reserved).Scan(&id); err != nil {
|
||||
if err := stmt.QueryRow(envId, shr.ZId, shr.Token, shr.ShareMode, shr.BackendMode, shr.FrontendSelection, shr.FrontendEndpoint, shr.BackendProxyEndpoint, shr.Reserved, shr.PermissionMode).Scan(&id); err != nil {
|
||||
return 0, errors.Wrap(err, "error executing shares insert statement")
|
||||
}
|
||||
return id, nil
|
||||
@ -96,12 +97,12 @@ func (str *Store) FindSharesForEnvironment(envId int, tx *sqlx.Tx) ([]*Share, er
|
||||
}
|
||||
|
||||
func (str *Store) UpdateShare(shr *Share, tx *sqlx.Tx) error {
|
||||
sql := "update shares set z_id = $1, token = $2, share_mode = $3, backend_mode = $4, frontend_selection = $5, frontend_endpoint = $6, backend_proxy_endpoint = $7, reserved = $8, updated_at = current_timestamp where id = $9"
|
||||
sql := "update shares set z_id = $1, token = $2, share_mode = $3, backend_mode = $4, frontend_selection = $5, frontend_endpoint = $6, backend_proxy_endpoint = $7, reserved = $8, permission_mode = $9, updated_at = current_timestamp where id = $10"
|
||||
stmt, err := tx.Prepare(sql)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error preparing shares update statement")
|
||||
}
|
||||
_, err = stmt.Exec(shr.ZId, shr.Token, shr.ShareMode, shr.BackendMode, shr.FrontendSelection, shr.FrontendEndpoint, shr.BackendProxyEndpoint, shr.Reserved, shr.Id)
|
||||
_, err = stmt.Exec(shr.ZId, shr.Token, shr.ShareMode, shr.BackendMode, shr.FrontendSelection, shr.FrontendEndpoint, shr.BackendProxyEndpoint, shr.Reserved, shr.PermissionMode, shr.Id)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error executing shares update statement")
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
-- +migrate Up
|
||||
|
||||
create type permission_mode_type as enum('open', 'closed');
|
||||
|
||||
alter table shares add column permission_mode permission_mode_type not null default('open');
|
||||
|
||||
create table access_grants (
|
||||
id serial primary key,
|
||||
share_id integer references shares(id),
|
||||
account_id integer references accounts(id),
|
||||
created_at timestamptz not null default(current_timestamp),
|
||||
updated_at timestamptz not null default(current_timestamp),
|
||||
deleted boolean not null default(false)
|
||||
);
|
@ -0,0 +1,12 @@
|
||||
-- +migrate Up
|
||||
|
||||
alter table shares add column permission_mode string not null default('open');
|
||||
|
||||
create table access_grants (
|
||||
id integer primary key,
|
||||
share_id integer references shares(id),
|
||||
account_id integer references accounts(id),
|
||||
created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')),
|
||||
deleted boolean not null default(false)
|
||||
);
|
@ -79,8 +79,12 @@ func (h *unshareHandler) Handle(params share.UnshareParams, principal *rest_mode
|
||||
h.deallocateResources(senv, shrToken, shrZId, edge)
|
||||
logrus.Debugf("deallocated share '%v'", shrToken)
|
||||
|
||||
if err := str.DeleteAccessGrantsForShare(sshr.Id, tx); err != nil {
|
||||
logrus.Errorf("error deleting access grants for share '%v': %v", shrToken, err)
|
||||
return share.NewUnshareInternalServerError()
|
||||
}
|
||||
if err := str.DeleteShare(sshr.Id, tx); err != nil {
|
||||
logrus.Errorf("error deactivating share '%v': %v", shrZId, err)
|
||||
logrus.Errorf("error deleting share '%v': %v", shrToken, err)
|
||||
return share.NewUnshareInternalServerError()
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
|
@ -48,15 +48,49 @@ func (h *updateShareHandler) Handle(params share.UpdateShareParams, principal *r
|
||||
return share.NewUpdateShareNotFound()
|
||||
}
|
||||
|
||||
sshr.BackendProxyEndpoint = &backendProxyEndpoint
|
||||
if err := str.UpdateShare(sshr, tx); err != nil {
|
||||
logrus.Errorf("error updating share '%v': %v", shrToken, err)
|
||||
return share.NewUpdateShareInternalServerError()
|
||||
doCommit := false
|
||||
if backendProxyEndpoint != "" {
|
||||
sshr.BackendProxyEndpoint = &backendProxyEndpoint
|
||||
if err := str.UpdateShare(sshr, tx); err != nil {
|
||||
logrus.Errorf("error updating share '%v': %v", shrToken, err)
|
||||
return share.NewUpdateShareInternalServerError()
|
||||
}
|
||||
doCommit = true
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
logrus.Errorf("error committing transaction for share '%v' update: %v", shrToken, err)
|
||||
return share.NewUpdateShareInternalServerError()
|
||||
for _, addr := range params.Body.AddAccessGrants {
|
||||
acct, err := str.FindAccountWithEmail(addr, tx)
|
||||
if err != nil {
|
||||
logrus.Errorf("error looking up account by email '%v' for user '%v': %v", addr, principal.Email, err)
|
||||
return share.NewUpdateShareBadRequest()
|
||||
}
|
||||
if _, err := str.CreateAccessGrant(sshr.Id, acct.Id, tx); err != nil {
|
||||
logrus.Errorf("error adding access grant '%v' for share '%v': %v", acct.Email, shrToken, err)
|
||||
return share.NewUpdateShareInternalServerError()
|
||||
}
|
||||
logrus.Infof("added access grant '%v' to share '%v'", acct.Email, shrToken)
|
||||
doCommit = true
|
||||
}
|
||||
|
||||
for _, addr := range params.Body.RemoveAccessGrants {
|
||||
acct, err := str.FindAccountWithEmail(addr, tx)
|
||||
if err != nil {
|
||||
logrus.Errorf("error looking up account by email '%v' for user '%v': %v", addr, principal.Email, err)
|
||||
return share.NewUpdateShareBadRequest()
|
||||
}
|
||||
if err := str.DeleteAccessGrantsForShareAndAccount(sshr.Id, acct.Id, tx); err != nil {
|
||||
logrus.Errorf("error removing access grant '%v' for share '%v': %v", acct.Email, shrToken, err)
|
||||
return share.NewUpdateShareInternalServerError()
|
||||
}
|
||||
logrus.Infof("removed access grant '%v' from share '%v'", acct.Email, shrToken)
|
||||
doCommit = true
|
||||
}
|
||||
|
||||
if doCommit {
|
||||
if err := tx.Commit(); err != nil {
|
||||
logrus.Errorf("error committing transaction for share '%v' update: %v", shrToken, err)
|
||||
return share.NewUpdateShareInternalServerError()
|
||||
}
|
||||
}
|
||||
|
||||
return share.NewUpdateShareOK()
|
||||
|
77
docs/guides/permission-modes.md
Normal file
77
docs/guides/permission-modes.md
Normal file
@ -0,0 +1,77 @@
|
||||
---
|
||||
sidebar_position: 22
|
||||
sidebar_label: Permission Modes
|
||||
---
|
||||
|
||||
# Permission Modes
|
||||
|
||||
Shares created in zrok `v0.4.26` and newer now include a choice of _permission mode_.
|
||||
|
||||
Shares created with zrok `v0.4.25` and older were created using what is now called the _open permission mode_. Whether _public_ or _private_, these shares can be accessed by any user of the zrok service instance, as long as they know the _share token_ of the share. Effectively shares with the _open permission mode_ are accessible by any user of the zrok service instance.
|
||||
|
||||
zrok now supports a _closed permission mode_, which allows for more fine-grained control over which zrok users are allowed to privately access your shares using `zrok access private`.
|
||||
|
||||
zrok defaults to continuing to create shares with the _open permission mode_. This will likely change in a future release. We're leaving the default behavior in place to allow users a period of time to get comfortable with the new permission modes.
|
||||
|
||||
## Creating a Share with Closed Permission Mode
|
||||
|
||||
Adding the `--closed` flag to the `zrok share` or `zrok reserve` commands will create shares using the _closed permission mode_:
|
||||
|
||||
```
|
||||
$ zrok share private --headless --closed -b web .
|
||||
[ 0.066] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:
|
||||
zrok access private 0vzwzodf0c7g
|
||||
```
|
||||
|
||||
By default any environment owned by the account that created the share is _allowed_ to access the new share. But a user trying to access the share from an environment owned by a different account will enounter the following error message:
|
||||
|
||||
```
|
||||
$ zrok access private 0vzwzodf0c7g
|
||||
[ERROR]: unable to access ([POST /access][401] accessUnauthorized)
|
||||
```
|
||||
|
||||
The `zrok share` and `zrok reserve` commands now include an `--access-grant` flag, which allows you to specify additional zrok accounts that are allowed to access your shares:
|
||||
|
||||
```
|
||||
$ zrok share private --headless --closed --access-grant anotheruser@test.com -b web .
|
||||
[ 0.062] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:
|
||||
zrok access private y6h4at5xvn6o
|
||||
```
|
||||
|
||||
And now `anotheruser@test.com` will be allowed to access the share:
|
||||
|
||||
```
|
||||
$ zrok access private --headless y6h4at5xvn6o
|
||||
[ 0.049] INFO main.(*accessPrivateCommand).run: allocated frontend 'VyvrJihAOEHD'
|
||||
[ 0.051] INFO main.(*accessPrivateCommand).run: access the zrok share at the following endpoint: http://127.0.0.1:9191
|
||||
```
|
||||
|
||||
## Adding and Removing Access Grants for Existing Shares
|
||||
|
||||
If you've created a share (either reserved or ephemeral) and you forgot to include an access grant, or want to remove an access grant that was mistakenly added, you can use the `zrok modify share` command to make the adjustments:
|
||||
|
||||
Create a share:
|
||||
|
||||
```
|
||||
$ zrok share private --headless --closed -b web .
|
||||
[ 0.064] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:
|
||||
zrok access private s4czjylwk7wa
|
||||
```
|
||||
|
||||
In another shell in the same environment you can execute:
|
||||
|
||||
```
|
||||
$ zrok modify share s4czjylwk7wa --add-access-grant anotheruser@test.com
|
||||
updated
|
||||
```
|
||||
|
||||
And to remove the grant:
|
||||
|
||||
```
|
||||
$ zrok modify share s4czjylwk7wa --remove-access-grant anotheruser@test.com
|
||||
updated
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
As of `v0.4.26` there is currently no way to _list_ the current access grants. This will be addressed shortly in a subsequent update.
|
@ -26,6 +26,12 @@ func (o *UpdateShareReader) ReadResponse(response runtime.ClientResponse, consum
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
case 400:
|
||||
result := NewUpdateShareBadRequest()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, result
|
||||
case 401:
|
||||
result := NewUpdateShareUnauthorized()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
@ -105,6 +111,62 @@ func (o *UpdateShareOK) readResponse(response runtime.ClientResponse, consumer r
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewUpdateShareBadRequest creates a UpdateShareBadRequest with default headers values
|
||||
func NewUpdateShareBadRequest() *UpdateShareBadRequest {
|
||||
return &UpdateShareBadRequest{}
|
||||
}
|
||||
|
||||
/*
|
||||
UpdateShareBadRequest describes a response with status code 400, with default header values.
|
||||
|
||||
bad request
|
||||
*/
|
||||
type UpdateShareBadRequest struct {
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this update share bad request response has a 2xx status code
|
||||
func (o *UpdateShareBadRequest) IsSuccess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this update share bad request response has a 3xx status code
|
||||
func (o *UpdateShareBadRequest) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this update share bad request response has a 4xx status code
|
||||
func (o *UpdateShareBadRequest) IsClientError() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsServerError returns true when this update share bad request response has a 5xx status code
|
||||
func (o *UpdateShareBadRequest) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this update share bad request response a status code equal to that given
|
||||
func (o *UpdateShareBadRequest) IsCode(code int) bool {
|
||||
return code == 400
|
||||
}
|
||||
|
||||
// Code gets the status code for the update share bad request response
|
||||
func (o *UpdateShareBadRequest) Code() int {
|
||||
return 400
|
||||
}
|
||||
|
||||
func (o *UpdateShareBadRequest) Error() string {
|
||||
return fmt.Sprintf("[PATCH /share][%d] updateShareBadRequest ", 400)
|
||||
}
|
||||
|
||||
func (o *UpdateShareBadRequest) String() string {
|
||||
return fmt.Sprintf("[PATCH /share][%d] updateShareBadRequest ", 400)
|
||||
}
|
||||
|
||||
func (o *UpdateShareBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewUpdateShareUnauthorized creates a UpdateShareUnauthorized with default headers values
|
||||
func NewUpdateShareUnauthorized() *UpdateShareUnauthorized {
|
||||
return &UpdateShareUnauthorized{}
|
||||
|
@ -21,6 +21,9 @@ import (
|
||||
// swagger:model shareRequest
|
||||
type ShareRequest struct {
|
||||
|
||||
// access grants
|
||||
AccessGrants []string `json:"accessGrants"`
|
||||
|
||||
// auth scheme
|
||||
AuthScheme string `json:"authScheme,omitempty"`
|
||||
|
||||
@ -50,6 +53,10 @@ type ShareRequest struct {
|
||||
// Enum: [github google]
|
||||
OauthProvider string `json:"oauthProvider,omitempty"`
|
||||
|
||||
// permission mode
|
||||
// Enum: [open closed]
|
||||
PermissionMode string `json:"permissionMode,omitempty"`
|
||||
|
||||
// reserved
|
||||
Reserved bool `json:"reserved,omitempty"`
|
||||
|
||||
@ -77,6 +84,10 @@ func (m *ShareRequest) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validatePermissionMode(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateShareMode(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@ -212,6 +223,48 @@ func (m *ShareRequest) validateOauthProvider(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var shareRequestTypePermissionModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["open","closed"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
shareRequestTypePermissionModePropEnum = append(shareRequestTypePermissionModePropEnum, v)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// ShareRequestPermissionModeOpen captures enum value "open"
|
||||
ShareRequestPermissionModeOpen string = "open"
|
||||
|
||||
// ShareRequestPermissionModeClosed captures enum value "closed"
|
||||
ShareRequestPermissionModeClosed string = "closed"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
func (m *ShareRequest) validatePermissionModeEnum(path, location string, value string) error {
|
||||
if err := validate.EnumCase(path, location, value, shareRequestTypePermissionModePropEnum, true); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ShareRequest) validatePermissionMode(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.PermissionMode) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
// value enum
|
||||
if err := m.validatePermissionModeEnum("permissionMode", "body", m.PermissionMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var shareRequestTypeShareModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
|
@ -17,9 +17,15 @@ import (
|
||||
// swagger:model updateShareRequest
|
||||
type UpdateShareRequest struct {
|
||||
|
||||
// add access grants
|
||||
AddAccessGrants []string `json:"addAccessGrants"`
|
||||
|
||||
// backend proxy endpoint
|
||||
BackendProxyEndpoint string `json:"backendProxyEndpoint,omitempty"`
|
||||
|
||||
// remove access grants
|
||||
RemoveAccessGrants []string `json:"removeAccessGrants"`
|
||||
|
||||
// shr token
|
||||
ShrToken string `json:"shrToken,omitempty"`
|
||||
}
|
||||
|
@ -988,6 +988,9 @@ func init() {
|
||||
"200": {
|
||||
"description": "share updated"
|
||||
},
|
||||
"400": {
|
||||
"description": "bad request"
|
||||
},
|
||||
"401": {
|
||||
"description": "unauthorized"
|
||||
},
|
||||
@ -1562,6 +1565,12 @@ func init() {
|
||||
"shareRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"accessGrants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"authScheme": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -1611,6 +1620,13 @@ func init() {
|
||||
"google"
|
||||
]
|
||||
},
|
||||
"permissionMode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"open",
|
||||
"closed"
|
||||
]
|
||||
},
|
||||
"reserved": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@ -1708,9 +1724,21 @@ func init() {
|
||||
"updateShareRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"addAccessGrants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"backendProxyEndpoint": {
|
||||
"type": "string"
|
||||
},
|
||||
"removeAccessGrants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"shrToken": {
|
||||
"type": "string"
|
||||
}
|
||||
@ -2715,6 +2743,9 @@ func init() {
|
||||
"200": {
|
||||
"description": "share updated"
|
||||
},
|
||||
"400": {
|
||||
"description": "bad request"
|
||||
},
|
||||
"401": {
|
||||
"description": "unauthorized"
|
||||
},
|
||||
@ -3289,6 +3320,12 @@ func init() {
|
||||
"shareRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"accessGrants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"authScheme": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3338,6 +3375,13 @@ func init() {
|
||||
"google"
|
||||
]
|
||||
},
|
||||
"permissionMode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"open",
|
||||
"closed"
|
||||
]
|
||||
},
|
||||
"reserved": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@ -3435,9 +3479,21 @@ func init() {
|
||||
"updateShareRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"addAccessGrants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"backendProxyEndpoint": {
|
||||
"type": "string"
|
||||
},
|
||||
"removeAccessGrants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"shrToken": {
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -36,6 +36,31 @@ func (o *UpdateShareOK) WriteResponse(rw http.ResponseWriter, producer runtime.P
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
|
||||
// UpdateShareBadRequestCode is the HTTP code returned for type UpdateShareBadRequest
|
||||
const UpdateShareBadRequestCode int = 400
|
||||
|
||||
/*
|
||||
UpdateShareBadRequest bad request
|
||||
|
||||
swagger:response updateShareBadRequest
|
||||
*/
|
||||
type UpdateShareBadRequest struct {
|
||||
}
|
||||
|
||||
// NewUpdateShareBadRequest creates UpdateShareBadRequest with default headers values
|
||||
func NewUpdateShareBadRequest() *UpdateShareBadRequest {
|
||||
|
||||
return &UpdateShareBadRequest{}
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *UpdateShareBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||
|
||||
rw.WriteHeader(400)
|
||||
}
|
||||
|
||||
// UpdateShareUnauthorizedCode is the HTTP code returned for type UpdateShareUnauthorized
|
||||
const UpdateShareUnauthorizedCode int = 401
|
||||
|
||||
|
@ -20,6 +20,13 @@ const (
|
||||
PublicShareMode ShareMode = "public"
|
||||
)
|
||||
|
||||
type PermissionMode string
|
||||
|
||||
const (
|
||||
OpenPermissionMode PermissionMode = "open"
|
||||
ClosedPermissionMode PermissionMode = "closed"
|
||||
)
|
||||
|
||||
type ShareRequest struct {
|
||||
Reserved bool
|
||||
UniqueName string
|
||||
@ -31,6 +38,8 @@ type ShareRequest struct {
|
||||
OauthProvider string
|
||||
OauthEmailAddressPatterns []string
|
||||
OauthAuthorizationCheckInterval time.Duration
|
||||
PermissionMode PermissionMode
|
||||
AccessGrants []string
|
||||
}
|
||||
|
||||
type Share struct {
|
||||
|
@ -71,6 +71,8 @@ func newPrivateShare(root env_core.Root, request *ShareRequest) *share.SharePara
|
||||
BackendMode: string(request.BackendMode),
|
||||
BackendProxyEndpoint: request.Target,
|
||||
AuthScheme: string(None),
|
||||
PermissionMode: string(request.PermissionMode),
|
||||
AccessGrants: request.AccessGrants,
|
||||
}
|
||||
return req
|
||||
}
|
||||
@ -87,6 +89,8 @@ func newPublicShare(root env_core.Root, request *ShareRequest) *share.ShareParam
|
||||
OauthEmailDomains: request.OauthEmailAddressPatterns,
|
||||
OauthProvider: request.OauthProvider,
|
||||
OauthAuthorizationCheckInterval: request.OauthAuthorizationCheckInterval.String(),
|
||||
PermissionMode: string(request.PermissionMode),
|
||||
AccessGrants: request.AccessGrants,
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ class ShareRequest(object):
|
||||
'oauth_email_domains': 'list[str]',
|
||||
'oauth_authorization_check_interval': 'str',
|
||||
'reserved': 'bool',
|
||||
'permission_mode': 'str',
|
||||
'access_grants': 'list[str]',
|
||||
'unique_name': 'str'
|
||||
}
|
||||
|
||||
@ -54,10 +56,12 @@ class ShareRequest(object):
|
||||
'oauth_email_domains': 'oauthEmailDomains',
|
||||
'oauth_authorization_check_interval': 'oauthAuthorizationCheckInterval',
|
||||
'reserved': 'reserved',
|
||||
'permission_mode': 'permissionMode',
|
||||
'access_grants': 'accessGrants',
|
||||
'unique_name': 'uniqueName'
|
||||
}
|
||||
|
||||
def __init__(self, env_zid=None, share_mode=None, frontend_selection=None, backend_mode=None, backend_proxy_endpoint=None, auth_scheme=None, auth_users=None, oauth_provider=None, oauth_email_domains=None, oauth_authorization_check_interval=None, reserved=None, unique_name=None): # noqa: E501
|
||||
def __init__(self, env_zid=None, share_mode=None, frontend_selection=None, backend_mode=None, backend_proxy_endpoint=None, auth_scheme=None, auth_users=None, oauth_provider=None, oauth_email_domains=None, oauth_authorization_check_interval=None, reserved=None, permission_mode=None, access_grants=None, unique_name=None): # noqa: E501
|
||||
"""ShareRequest - a model defined in Swagger""" # noqa: E501
|
||||
self._env_zid = None
|
||||
self._share_mode = None
|
||||
@ -70,6 +74,8 @@ class ShareRequest(object):
|
||||
self._oauth_email_domains = None
|
||||
self._oauth_authorization_check_interval = None
|
||||
self._reserved = None
|
||||
self._permission_mode = None
|
||||
self._access_grants = None
|
||||
self._unique_name = None
|
||||
self.discriminator = None
|
||||
if env_zid is not None:
|
||||
@ -94,6 +100,10 @@ class ShareRequest(object):
|
||||
self.oauth_authorization_check_interval = oauth_authorization_check_interval
|
||||
if reserved is not None:
|
||||
self.reserved = reserved
|
||||
if permission_mode is not None:
|
||||
self.permission_mode = permission_mode
|
||||
if access_grants is not None:
|
||||
self.access_grants = access_grants
|
||||
if unique_name is not None:
|
||||
self.unique_name = unique_name
|
||||
|
||||
@ -346,6 +356,54 @@ class ShareRequest(object):
|
||||
|
||||
self._reserved = reserved
|
||||
|
||||
@property
|
||||
def permission_mode(self):
|
||||
"""Gets the permission_mode of this ShareRequest. # noqa: E501
|
||||
|
||||
|
||||
:return: The permission_mode of this ShareRequest. # noqa: E501
|
||||
:rtype: str
|
||||
"""
|
||||
return self._permission_mode
|
||||
|
||||
@permission_mode.setter
|
||||
def permission_mode(self, permission_mode):
|
||||
"""Sets the permission_mode of this ShareRequest.
|
||||
|
||||
|
||||
:param permission_mode: The permission_mode of this ShareRequest. # noqa: E501
|
||||
:type: str
|
||||
"""
|
||||
allowed_values = ["open", "closed"] # noqa: E501
|
||||
if permission_mode not in allowed_values:
|
||||
raise ValueError(
|
||||
"Invalid value for `permission_mode` ({0}), must be one of {1}" # noqa: E501
|
||||
.format(permission_mode, allowed_values)
|
||||
)
|
||||
|
||||
self._permission_mode = permission_mode
|
||||
|
||||
@property
|
||||
def access_grants(self):
|
||||
"""Gets the access_grants of this ShareRequest. # noqa: E501
|
||||
|
||||
|
||||
:return: The access_grants of this ShareRequest. # noqa: E501
|
||||
:rtype: list[str]
|
||||
"""
|
||||
return self._access_grants
|
||||
|
||||
@access_grants.setter
|
||||
def access_grants(self, access_grants):
|
||||
"""Sets the access_grants of this ShareRequest.
|
||||
|
||||
|
||||
:param access_grants: The access_grants of this ShareRequest. # noqa: E501
|
||||
:type: list[str]
|
||||
"""
|
||||
|
||||
self._access_grants = access_grants
|
||||
|
||||
@property
|
||||
def unique_name(self):
|
||||
"""Gets the unique_name of this ShareRequest. # noqa: E501
|
||||
|
@ -29,23 +29,33 @@ class UpdateShareRequest(object):
|
||||
"""
|
||||
swagger_types = {
|
||||
'shr_token': 'str',
|
||||
'backend_proxy_endpoint': 'str'
|
||||
'backend_proxy_endpoint': 'str',
|
||||
'add_access_grants': 'list[str]',
|
||||
'remove_access_grants': 'list[str]'
|
||||
}
|
||||
|
||||
attribute_map = {
|
||||
'shr_token': 'shrToken',
|
||||
'backend_proxy_endpoint': 'backendProxyEndpoint'
|
||||
'backend_proxy_endpoint': 'backendProxyEndpoint',
|
||||
'add_access_grants': 'addAccessGrants',
|
||||
'remove_access_grants': 'removeAccessGrants'
|
||||
}
|
||||
|
||||
def __init__(self, shr_token=None, backend_proxy_endpoint=None): # noqa: E501
|
||||
def __init__(self, shr_token=None, backend_proxy_endpoint=None, add_access_grants=None, remove_access_grants=None): # noqa: E501
|
||||
"""UpdateShareRequest - a model defined in Swagger""" # noqa: E501
|
||||
self._shr_token = None
|
||||
self._backend_proxy_endpoint = None
|
||||
self._add_access_grants = None
|
||||
self._remove_access_grants = None
|
||||
self.discriminator = None
|
||||
if shr_token is not None:
|
||||
self.shr_token = shr_token
|
||||
if backend_proxy_endpoint is not None:
|
||||
self.backend_proxy_endpoint = backend_proxy_endpoint
|
||||
if add_access_grants is not None:
|
||||
self.add_access_grants = add_access_grants
|
||||
if remove_access_grants is not None:
|
||||
self.remove_access_grants = remove_access_grants
|
||||
|
||||
@property
|
||||
def shr_token(self):
|
||||
@ -89,6 +99,48 @@ class UpdateShareRequest(object):
|
||||
|
||||
self._backend_proxy_endpoint = backend_proxy_endpoint
|
||||
|
||||
@property
|
||||
def add_access_grants(self):
|
||||
"""Gets the add_access_grants of this UpdateShareRequest. # noqa: E501
|
||||
|
||||
|
||||
:return: The add_access_grants of this UpdateShareRequest. # noqa: E501
|
||||
:rtype: list[str]
|
||||
"""
|
||||
return self._add_access_grants
|
||||
|
||||
@add_access_grants.setter
|
||||
def add_access_grants(self, add_access_grants):
|
||||
"""Sets the add_access_grants of this UpdateShareRequest.
|
||||
|
||||
|
||||
:param add_access_grants: The add_access_grants of this UpdateShareRequest. # noqa: E501
|
||||
:type: list[str]
|
||||
"""
|
||||
|
||||
self._add_access_grants = add_access_grants
|
||||
|
||||
@property
|
||||
def remove_access_grants(self):
|
||||
"""Gets the remove_access_grants of this UpdateShareRequest. # noqa: E501
|
||||
|
||||
|
||||
:return: The remove_access_grants of this UpdateShareRequest. # noqa: E501
|
||||
:rtype: list[str]
|
||||
"""
|
||||
return self._remove_access_grants
|
||||
|
||||
@remove_access_grants.setter
|
||||
def remove_access_grants(self, remove_access_grants):
|
||||
"""Sets the remove_access_grants of this UpdateShareRequest.
|
||||
|
||||
|
||||
:param remove_access_grants: The remove_access_grants of this UpdateShareRequest. # noqa: E501
|
||||
:type: list[str]
|
||||
"""
|
||||
|
||||
self._remove_access_grants = remove_access_grants
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the model properties as a dict"""
|
||||
result = {}
|
||||
|
@ -651,6 +651,8 @@ paths:
|
||||
responses:
|
||||
200:
|
||||
description: share updated
|
||||
400:
|
||||
description: bad request
|
||||
401:
|
||||
description: unauthorized
|
||||
404:
|
||||
@ -1057,6 +1059,13 @@ definitions:
|
||||
type: string
|
||||
reserved:
|
||||
type: boolean
|
||||
permissionMode:
|
||||
type: string
|
||||
enum: ["open", "closed"]
|
||||
accessGrants:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
uniqueName:
|
||||
type: string
|
||||
|
||||
@ -1120,6 +1129,14 @@ definitions:
|
||||
type: string
|
||||
backendProxyEndpoint:
|
||||
type: string
|
||||
addAccessGrants:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
removeAccessGrants:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
verifyRequest:
|
||||
type: object
|
||||
|
@ -267,6 +267,8 @@
|
||||
* @property {string[]} oauthEmailDomains
|
||||
* @property {string} oauthAuthorizationCheckInterval
|
||||
* @property {boolean} reserved
|
||||
* @property {string} permissionMode
|
||||
* @property {string[]} accessGrants
|
||||
* @property {string} uniqueName
|
||||
*/
|
||||
|
||||
@ -319,6 +321,8 @@
|
||||
*
|
||||
* @property {string} shrToken
|
||||
* @property {string} backendProxyEndpoint
|
||||
* @property {string[]} addAccessGrants
|
||||
* @property {string[]} removeAccessGrants
|
||||
*/
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user