Authenticate Handler API and SDK, and much more (#183)
This commit is contained in:
1 parent
acce195dcb
commit
28dbcd84bd
89 files changed
+5296
-1943
No files matched your search
@@ -0,0 +1,78 @@
|
||||
// Code generated by "make api"; DO NOT EDIT.
|
||||
package authtokens
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/api/internal/strutil"
|
||||
)
|
||||
|
||||
type AuthToken struct {
|
||||
Client *api.Client `json:"-"`
|
||||
|
||||
defaultFields []string
|
||||
|
||||
// The ID of the AuthToken
|
||||
// Output only.
|
||||
Id string `json:"id,omitempty"`
|
||||
// The token. This will only be populated after login and is only ever visible to the end user whose login
|
||||
// request resulted in this auth token being created.
|
||||
// Output only.
|
||||
Token string `json:"token,omitempty"`
|
||||
// The id of the user of this AuthToken.
|
||||
// Output only.
|
||||
UserId string `json:"user_id,omitempty"`
|
||||
// The id of the user of this AuthToken.
|
||||
// Output only.
|
||||
AuthMethodId string `json:"auth_method_id,omitempty"`
|
||||
// The time this resource was created
|
||||
// Output only.
|
||||
CreatedTime time.Time `json:"created_time,omitempty"`
|
||||
// The time this resource was last updated.
|
||||
// Output only.
|
||||
UpdatedTime time.Time `json:"updated_time,omitempty"`
|
||||
// The approximate time this AuthToken was last used.
|
||||
// Output only.
|
||||
ApproximateLastUsedTime time.Time `json:"approximate_last_used_time,omitempty"`
|
||||
// The time this AuthToken expires.
|
||||
// Output only.
|
||||
ExpirationTime time.Time `json:"expiration_time,omitempty"`
|
||||
}
|
||||
|
||||
func (s *AuthToken) SetDefault(key string) {
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"approximatelastusedtime": "approximate_last_used_time", "authmethodid": "auth_method_id", "createdtime": "created_time", "expirationtime": "expiration_time", "id": "id", "token": "token", "updatedtime": "updated_time", "userid": "user_id"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AuthToken) UnsetDefault(key string) {
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"approximatelastusedtime": "approximate_last_used_time", "authmethodid": "auth_method_id", "createdtime": "created_time", "expirationtime": "expiration_time", "id": "id", "token": "token", "updatedtime": "updated_time", "userid": "user_id"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s AuthToken) MarshalJSON() ([]byte, error) {
|
||||
m := structs.Map(s)
|
||||
if m == nil {
|
||||
m = make(map[string]interface{})
|
||||
}
|
||||
for _, k := range s.defaultFields {
|
||||
m[k] = nil
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+39
-7
@@ -143,6 +143,7 @@ func DefaultConfig() (*Config, error) {
|
||||
Addr: "https://127.0.0.1:9200",
|
||||
HttpClient: cleanhttp.DefaultPooledClient(),
|
||||
Timeout: time.Second * 60,
|
||||
TLSConfig: &TLSConfig{},
|
||||
}
|
||||
|
||||
// We read the environment now; after DefaultClient returns we can override
|
||||
@@ -217,10 +218,10 @@ func (c *Config) ConfigureTLS() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// setAddress parses a given string and looks for org and project info, setting
|
||||
// the actual address to the base. Note that if a very malformed URL is passed
|
||||
// in, this may not return what one expects. For now this is on purpose to
|
||||
// avoid requiring error handling.
|
||||
// setAddr parses a given string and looks for org and project info, setting the
|
||||
// actual address to the base. Note that if a very malformed URL is passed in,
|
||||
// this may not return what one expects. For now this is on purpose to avoid
|
||||
// requiring error handling.
|
||||
//
|
||||
// This also removes any trailing "/v1"; we'll use that in our commands so we
|
||||
// don't require it from users.
|
||||
@@ -449,6 +450,14 @@ func (c *Client) SetAddr(addr string) error {
|
||||
return c.config.setAddr(addr)
|
||||
}
|
||||
|
||||
// Org fetches the org the client will use by default
|
||||
func (c *Client) Org() string {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
|
||||
return c.config.Org
|
||||
}
|
||||
|
||||
// SetOrg sets the org the client will use by default
|
||||
func (c *Client) SetOrg(org string) {
|
||||
c.modifyLock.Lock()
|
||||
@@ -457,6 +466,14 @@ func (c *Client) SetOrg(org string) {
|
||||
c.config.Org = org
|
||||
}
|
||||
|
||||
// Project fetches the project the client will use by default
|
||||
func (c *Client) Project() string {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
|
||||
return c.config.Project
|
||||
}
|
||||
|
||||
// SetProject sets the project the client will use by default
|
||||
func (c *Client) SetProject(project string) {
|
||||
c.modifyLock.Lock()
|
||||
@@ -519,6 +536,14 @@ func (c *Client) SetOutputCurlString(curl bool) {
|
||||
c.config.OutputCurlString = curl
|
||||
}
|
||||
|
||||
// Token gets the configured token.
|
||||
func (c *Client) Token() string {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
|
||||
return c.config.Token
|
||||
}
|
||||
|
||||
// SetToken sets the token directly. This won't perform any auth
|
||||
// verification, it simply sets the token properly for future requests.
|
||||
func (c *Client) SetToken(token string) {
|
||||
@@ -700,18 +725,25 @@ func (c *Client) NewRequest(ctx context.Context, method, requestPath string, bod
|
||||
orgProjPath = path.Join(orgProjPath, "projects", project)
|
||||
}
|
||||
|
||||
p := path.Join(u.Path, "/v1", orgProjPath)
|
||||
if strings.HasPrefix(requestPath, ":") {
|
||||
p = p + requestPath
|
||||
} else {
|
||||
p = path.Join(p, requestPath)
|
||||
}
|
||||
|
||||
req := &http.Request{
|
||||
Method: method,
|
||||
URL: &url.URL{
|
||||
User: u.User,
|
||||
Scheme: u.Scheme,
|
||||
Host: host,
|
||||
Path: path.Join(u.Path, "/v1", orgProjPath, requestPath),
|
||||
Path: p,
|
||||
},
|
||||
Host: u.Host,
|
||||
}
|
||||
req.Header = headers
|
||||
req.Header.Add("authorization", "bearer: "+token)
|
||||
req.Header.Add("authorization", "Bearer "+token)
|
||||
req.Header.Set("content-type", "application/json")
|
||||
if ctx != nil {
|
||||
req = req.WithContext(ctx)
|
||||
@@ -786,7 +818,7 @@ func (c *Client) Do(r *retryablehttp.Request) (*Response, error) {
|
||||
}
|
||||
|
||||
result, err := client.Do(r)
|
||||
if result != nil && err == nil && result.StatusCode == 307 {
|
||||
if result != nil && err == nil && result.StatusCode == http.StatusTemporaryRedirect {
|
||||
loc, err := result.Location()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting new location during redirect: %w", err)
|
||||
|
||||
+20
-5
@@ -3,6 +3,7 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
@@ -13,22 +14,36 @@ type Error struct {
|
||||
defaultFields []string
|
||||
|
||||
// The HTTP Status code applicable to this error
|
||||
Status *int32 `json:"status,omitempty"`
|
||||
Status int32 `json:"status,omitempty"`
|
||||
// An application-specific error string
|
||||
Code *string `json:"code,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
// A human readable explanation specific to this occurrence of the error
|
||||
Message *string `json:"message,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
// Additional metadata regarding the error. Depending on the error
|
||||
// different fields will be populated.
|
||||
Details *ErrorDetails `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Error) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"code": "code", "details": "details", "message": "message", "status": "status"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Error) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"code": "code", "details": "details", "message": "message", "status": "status"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Error) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
@@ -12,17 +13,31 @@ import (
|
||||
type ErrorDetails struct {
|
||||
defaultFields []string
|
||||
|
||||
TraceId *string `json:"TraceId,omitempty"`
|
||||
RequestId *string `json:"request_id,omitempty"`
|
||||
TraceId string `json:"TraceId,omitempty"`
|
||||
RequestId string `json:"request_id,omitempty"`
|
||||
RequestFields []*FieldError `json:"request_fields,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ErrorDetails) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"requestfields": "request_fields", "requestid": "request_id", "traceid": "TraceId"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ErrorDetails) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"requestfields": "request_fields", "requestid": "request_id", "traceid": "TraceId"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s ErrorDetails) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+19
-4
@@ -3,6 +3,7 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
@@ -12,16 +13,30 @@ import (
|
||||
type FieldError struct {
|
||||
defaultFields []string
|
||||
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
func (s *FieldError) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"description": "description", "name": "name"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FieldError) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"description": "description", "name": "name"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s FieldError) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+17
-2
@@ -3,6 +3,7 @@ package groups
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -34,11 +35,25 @@ type Group struct {
|
||||
}
|
||||
|
||||
func (s *Group) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Group) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Group) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -116,8 +116,8 @@ func TestGroup_Crud(t *testing.T) {
|
||||
checkGroup := func(step string, g *groups.Group, apiErr *api.Error, err error, wantedName string) {
|
||||
assert := assert.New(t)
|
||||
assert.NoError(err, step)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != nil {
|
||||
t.Errorf("ApiError message: %q", *apiErr.Message)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != "" {
|
||||
t.Errorf("ApiError message: %q", apiErr.Message)
|
||||
}
|
||||
assert.NotNil(g, "returned no resource", step)
|
||||
gotName := ""
|
||||
@@ -216,17 +216,17 @@ func TestGroup_Errors(t *testing.T) {
|
||||
_, apiErr, err = tt.scope.ReadGroup(ctx, &groups.Group{Id: iam.GroupPrefix + "_doesntexis"})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusNotFound)
|
||||
assert.EqualValues(apiErr.Status, http.StatusNotFound)
|
||||
|
||||
_, apiErr, err = tt.scope.ReadGroup(ctx, &groups.Group{Id: "invalid id"})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
|
||||
_, apiErr, err = tt.scope.UpdateGroup(ctx, &groups.Group{Id: u.Id})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
})
|
||||
}
|
||||
}
|
||||
+17
-2
@@ -3,6 +3,7 @@ package hosts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -38,11 +39,25 @@ type Host struct {
|
||||
}
|
||||
|
||||
func (s *Host) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"address": "address", "createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "type": "type", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Host) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"address": "address", "createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "type": "type", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Host) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package hosts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -39,11 +40,25 @@ type HostCatalog struct {
|
||||
}
|
||||
|
||||
func (s *HostCatalog) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"attributes": "attributes", "createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "type": "type", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HostCatalog) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"attributes": "attributes", "createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "type": "type", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s HostCatalog) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -29,8 +29,8 @@ func TestCatalogs_Crud(t *testing.T) {
|
||||
checkCatalog := func(step string, hc *hosts.HostCatalog, apiErr *api.Error, err error, wantedName string) {
|
||||
assert := assert.New(t)
|
||||
assert.NoError(err, step)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != nil {
|
||||
t.Errorf("ApiError message: %q", *apiErr.Message)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != "" {
|
||||
t.Errorf("ApiError message: %q", apiErr.Message)
|
||||
}
|
||||
assert.NotNil(hc, "returned no resource", step)
|
||||
gotName := ""
|
||||
@@ -94,15 +94,15 @@ func TestCatalogs_Errors(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
// TODO: Should this be nil instead of just a catalog that has no values set
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusNotFound)
|
||||
assert.EqualValues(apiErr.Status, http.StatusNotFound)
|
||||
|
||||
_, apiErr, err = p.ReadHostCatalog(ctx, &hosts.HostCatalog{Id: "invalid id"})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
|
||||
_, apiErr, err = p.UpdateHostCatalog(ctx, &hosts.HostCatalog{Id: hc.Id, Type: api.String("Cant Update")})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package hosts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -44,11 +45,25 @@ type HostSet struct {
|
||||
}
|
||||
|
||||
func (s *HostSet) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "hosts": "hosts", "id": "id", "name": "name", "size": "size", "type": "type", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HostSet) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "hosts": "hosts", "id": "id", "name": "name", "size": "size", "type": "type", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s HostSet) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+86
-117
@@ -12,150 +12,119 @@ type structInfo struct {
|
||||
parentName string
|
||||
detailName string
|
||||
templateType templateType
|
||||
nameJsonMap map[string]string
|
||||
}
|
||||
|
||||
var inputStructs = []*structInfo{
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
|
||||
"Error",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/error.gen.go",
|
||||
"Error",
|
||||
"api",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
|
||||
inName: "Error",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/error.gen.go",
|
||||
outName: "Error",
|
||||
outPkg: "api",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
|
||||
"ErrorDetails",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/error_details.gen.go",
|
||||
"ErrorDetails",
|
||||
"api",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
|
||||
inName: "ErrorDetails",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/error_details.gen.go",
|
||||
outName: "ErrorDetails",
|
||||
outPkg: "api",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
|
||||
"FieldError",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/field_error.gen.go",
|
||||
"FieldError",
|
||||
"api",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/error.pb.go",
|
||||
inName: "FieldError",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/field_error.gen.go",
|
||||
outName: "FieldError",
|
||||
outPkg: "api",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host.pb.go",
|
||||
"Host",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/hosts/host.gen.go",
|
||||
"Host",
|
||||
"hosts",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host.pb.go",
|
||||
inName: "Host",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/hosts/host.gen.go",
|
||||
outName: "Host",
|
||||
outPkg: "hosts",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_set.pb.go",
|
||||
"HostSet",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/hosts/host_set.gen.go",
|
||||
"HostSet",
|
||||
"hosts",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_set.pb.go",
|
||||
inName: "HostSet",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/hosts/host_set.gen.go",
|
||||
outName: "HostSet",
|
||||
outPkg: "hosts",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
|
||||
"HostCatalog",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/hosts/host_catalog.gen.go",
|
||||
"HostCatalog",
|
||||
"hosts",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
|
||||
inName: "HostCatalog",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/hosts/host_catalog.gen.go",
|
||||
outName: "HostCatalog",
|
||||
outPkg: "hosts",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/scopes/org.pb.go",
|
||||
"Org",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/scopes/org.gen.go",
|
||||
"Org",
|
||||
"scopes",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/scopes/org.pb.go",
|
||||
inName: "Org",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/scopes/org.gen.go",
|
||||
outName: "Org",
|
||||
outPkg: "scopes",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/scopes/project.pb.go",
|
||||
"Project",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/scopes/project.gen.go",
|
||||
"Project",
|
||||
"scopes",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/authtokens/authtoken.pb.go",
|
||||
inName: "AuthToken",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/authtokens/authtoken.gen.go",
|
||||
outName: "AuthToken",
|
||||
outPkg: "authtokens",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/users/user.pb.go",
|
||||
"User",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/users/user.gen.go",
|
||||
"User",
|
||||
"users",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/scopes/project.pb.go",
|
||||
inName: "Project",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/scopes/project.gen.go",
|
||||
outName: "Project",
|
||||
outPkg: "scopes",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/groups/group.pb.go",
|
||||
"Group",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/groups/group.gen.go",
|
||||
"Group",
|
||||
"groups",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/users/user.pb.go",
|
||||
inName: "User",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/users/user.gen.go",
|
||||
outName: "User",
|
||||
outPkg: "users",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/roles/role.pb.go",
|
||||
"Role",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/roles/role.gen.go",
|
||||
"Role",
|
||||
"roles",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
templateTypeResource,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/groups/group.pb.go",
|
||||
inName: "Group",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/groups/group.gen.go",
|
||||
outName: "Group",
|
||||
outPkg: "groups",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
|
||||
"StaticHostCatalogDetails",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/hosts/static_host_catalog.gen.go",
|
||||
"StaticHostCatalogDetails",
|
||||
"hosts",
|
||||
"",
|
||||
"HostCatalog",
|
||||
"StaticHostCatalog",
|
||||
templateTypeDetail,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/roles/role.pb.go",
|
||||
inName: "Role",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/roles/role.gen.go",
|
||||
outName: "Role",
|
||||
outPkg: "roles",
|
||||
},
|
||||
{
|
||||
os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
|
||||
"AwsEc2HostCatalogDetails",
|
||||
os.Getenv("GEN_BASEPATH") + "/api/hosts/awsec2_host_catalog.gen.go",
|
||||
"AwsEc2HostCatalogDetails",
|
||||
"hosts",
|
||||
"",
|
||||
"HostCatalog",
|
||||
"AwsEc2HostCatalog",
|
||||
templateTypeDetail,
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/roles/role.pb.go",
|
||||
inName: "Principal",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/roles/principal.gen.go",
|
||||
outName: "Principal",
|
||||
outPkg: "roles",
|
||||
},
|
||||
{
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
|
||||
inName: "StaticHostCatalogDetails",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/hosts/static_host_catalog.gen.go",
|
||||
outName: "StaticHostCatalogDetails",
|
||||
outPkg: "hosts",
|
||||
parentName: "HostCatalog",
|
||||
detailName: "StaticHostCatalog",
|
||||
templateType: templateTypeDetail,
|
||||
},
|
||||
{
|
||||
inFile: os.Getenv("GEN_BASEPATH") + "/internal/gen/controller/api/resources/hosts/host_catalog.pb.go",
|
||||
inName: "AwsEc2HostCatalogDetails",
|
||||
outFile: os.Getenv("GEN_BASEPATH") + "/api/hosts/awsec2_host_catalog.gen.go",
|
||||
outName: "AwsEc2HostCatalogDetails",
|
||||
outPkg: "hosts",
|
||||
parentName: "HostCatalog",
|
||||
detailName: "AwsEc2HostCatalog",
|
||||
templateType: templateTypeDetail,
|
||||
},
|
||||
}
|
||||
@@ -38,6 +38,7 @@ func parsePBs() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
inputStruct.nameJsonMap = make(map[string]string)
|
||||
ast.Walk(visitFn(func(n ast.Node) {
|
||||
spec, ok := n.(*ast.TypeSpec)
|
||||
if !ok {
|
||||
@@ -114,11 +115,6 @@ func parsePBs() {
|
||||
var selectorExpr *ast.SelectorExpr
|
||||
switch typ := field.Type.(type) {
|
||||
case *ast.Ident:
|
||||
// Id values are immutable and should always exist, so
|
||||
// don't make it a pointer
|
||||
if field.Names[0].Name != "Id" {
|
||||
typ.Name = "*" + typ.Name
|
||||
}
|
||||
goto TAGMODIFY
|
||||
case *ast.ArrayType:
|
||||
goto TAGMODIFY
|
||||
@@ -222,7 +218,10 @@ func parsePBs() {
|
||||
}
|
||||
|
||||
TAGMODIFY:
|
||||
st.Fields.List[i].Tag.Value = "`" + regex.FindString(st.Fields.List[i].Tag.Value) + "`"
|
||||
tagString := regex.FindString(st.Fields.List[i].Tag.Value)
|
||||
st.Fields.List[i].Tag.Value = "`" + tagString + "`"
|
||||
tagString = strings.TrimSuffix(strings.TrimPrefix(tagString, `json:"`), `,omitempty"`)
|
||||
inputStruct.nameJsonMap[strings.ToLower(field.Names[0].Name)] = tagString
|
||||
}
|
||||
}), inAst)
|
||||
|
||||
|
||||
@@ -37,11 +37,6 @@ var readFuncs = map[string][]*readInfo{
|
||||
targetType: "users.User",
|
||||
path: "users",
|
||||
},
|
||||
{
|
||||
baseType: "Project",
|
||||
targetType: "hosts.HostCatalog",
|
||||
path: "host-catalogs",
|
||||
},
|
||||
{
|
||||
baseType: "Project",
|
||||
targetType: "groups.Group",
|
||||
@@ -52,6 +47,11 @@ var readFuncs = map[string][]*readInfo{
|
||||
targetType: "roles.Role",
|
||||
path: "roles",
|
||||
},
|
||||
{
|
||||
baseType: "Project",
|
||||
targetType: "hosts.HostCatalog",
|
||||
path: "host-catalogs",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,12 @@ func writeStructTemplates() {
|
||||
Name string
|
||||
Package string
|
||||
StructFields string
|
||||
NameJsonMap map[string]string
|
||||
}{
|
||||
Name: inputStruct.outName,
|
||||
Package: inputStruct.outPkg,
|
||||
StructFields: inputStruct.structFields,
|
||||
NameJsonMap: inputStruct.nameJsonMap,
|
||||
})
|
||||
|
||||
case templateTypeDetail:
|
||||
@@ -61,11 +63,12 @@ func writeStructTemplates() {
|
||||
// TODO: Add documentation around SetDefault and how it behaves when the field corresponding to the provided key is already set.
|
||||
var structTemplate = template.Must(template.New("").Parse(
|
||||
`// Code generated by "make api"; DO NOT EDIT.
|
||||
package {{ .Package }}
|
||||
package {{ .Package }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
@@ -82,11 +85,25 @@ type {{ .Name }} struct {
|
||||
}
|
||||
|
||||
func (s *{{ .Name }}) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := {{ printf "%#v" .NameJsonMap }}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *{{ .Name }}) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := {{ printf "%#v" .NameJsonMap }}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s {{ .Name }}) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+26
-11
@@ -32,25 +32,40 @@ func (r *Response) Decode(inStruct interface{}) (*Error, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// TODO Remove as we'll use the common err format for this
|
||||
if r.resp.StatusCode == 403 {
|
||||
// Nothing to be done
|
||||
return &Error{
|
||||
Status: http.StatusForbidden,
|
||||
Message: "Forbidden",
|
||||
}, nil
|
||||
}
|
||||
|
||||
if inStruct == nil {
|
||||
return nil, fmt.Errorf("nil value given to decode into and not a 204 response")
|
||||
}
|
||||
|
||||
r.Body = new(bytes.Buffer)
|
||||
if _, err := r.Body.ReadFrom(r.resp.Body); err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
apiErr := &Error{
|
||||
Status: int32(r.resp.StatusCode),
|
||||
}
|
||||
if r.resp.Body != nil {
|
||||
r.Body = new(bytes.Buffer)
|
||||
if _, err := r.Body.ReadFrom(r.resp.Body); err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(bytes.NewReader(r.Body.Bytes()))
|
||||
var apiErr Error
|
||||
if r.resp.StatusCode >= 400 {
|
||||
inStruct = &apiErr
|
||||
}
|
||||
if err := dec.Decode(inStruct); err != nil {
|
||||
return nil, fmt.Errorf("error decoding response: %w; response was %s", err, r.Body.String())
|
||||
if r.Body.Len() != 0 {
|
||||
dec := json.NewDecoder(bytes.NewReader(r.Body.Bytes()))
|
||||
if r.resp.StatusCode >= 400 {
|
||||
inStruct = apiErr
|
||||
}
|
||||
if err := dec.Decode(inStruct); err != nil {
|
||||
return nil, fmt.Errorf("error decoding response: %w; response was %s", err, r.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.resp.StatusCode >= 400 {
|
||||
return &apiErr, nil
|
||||
return apiErr, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
+29
-15
@@ -7,16 +7,17 @@ import (
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
)
|
||||
|
||||
func (s Role) AddPrincipals(ctx context.Context, groups, users []string) (*Role, *api.Error, error) {
|
||||
func (s Role) AddPrincipals(ctx context.Context, principalIds []string) (*Role, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in AddPrincipals request")
|
||||
}
|
||||
// We assume that the client provided has the org and optionally the project id of the request.
|
||||
|
||||
body := map[string]interface{}{
|
||||
"group_ids": groups,
|
||||
"user_ids": users,
|
||||
"version": s.Version,
|
||||
"version": s.Version,
|
||||
}
|
||||
if len(principalIds) > 0 {
|
||||
body["principal_ids"] = principalIds
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:add-principals", s.Id), body)
|
||||
@@ -40,16 +41,20 @@ func (s Role) AddPrincipals(ctx context.Context, groups, users []string) (*Role,
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (s Role) SetPrincipals(ctx context.Context, groups, users []string) (*Role, *api.Error, error) {
|
||||
func (s Role) SetPrincipals(ctx context.Context, principalIds []string) (*Role, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in SetPrincipals request")
|
||||
}
|
||||
// We assume that the client provided has the org and optionally the project id of the request.
|
||||
|
||||
body := map[string]interface{}{
|
||||
"group_ids": groups,
|
||||
"user_ids": users,
|
||||
"version": s.Version,
|
||||
"version": s.Version,
|
||||
}
|
||||
if len(principalIds) > 0 {
|
||||
body["principal_ids"] = principalIds
|
||||
} else if principalIds != nil {
|
||||
// In this function, a non-nil but empty list means clear out
|
||||
body["principal_ids"] = nil
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:set-principals", s.Id), body)
|
||||
@@ -73,16 +78,17 @@ func (s Role) SetPrincipals(ctx context.Context, groups, users []string) (*Role,
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (s Role) RemovePrincipals(ctx context.Context, groups, users []string) (*Role, *api.Error, error) {
|
||||
func (s Role) RemovePrincipals(ctx context.Context, principalIds []string) (*Role, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in RemovePrincipals request")
|
||||
}
|
||||
// We assume that the client provided has the org and optionally the project id of the request.
|
||||
|
||||
body := map[string]interface{}{
|
||||
"group_ids": groups,
|
||||
"user_ids": users,
|
||||
"version": s.Version,
|
||||
"version": s.Version,
|
||||
}
|
||||
if len(principalIds) > 0 {
|
||||
body["principal_ids"] = principalIds
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:remove-principals", s.Id), body)
|
||||
@@ -113,9 +119,11 @@ func (s Role) AddGrants(ctx context.Context, grants []string) (*Role, *api.Error
|
||||
// We assume that the client provided has the org and optionally the project id of the request.
|
||||
|
||||
body := map[string]interface{}{
|
||||
"grants": grants,
|
||||
"version": s.Version,
|
||||
}
|
||||
if len(grants) > 0 {
|
||||
body["grants"] = grants
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:add-grants", s.Id), body)
|
||||
if err != nil {
|
||||
@@ -145,9 +153,13 @@ func (s Role) SetGrants(ctx context.Context, grants []string) (*Role, *api.Error
|
||||
// We assume that the client provided has the org and optionally the project id of the request.
|
||||
|
||||
body := map[string]interface{}{
|
||||
"grants": grants,
|
||||
"version": s.Version,
|
||||
}
|
||||
if len(grants) > 0 {
|
||||
body["grants"] = grants
|
||||
} else if grants != nil {
|
||||
body["grants"] = nil
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:set-grants", s.Id), body)
|
||||
if err != nil {
|
||||
@@ -177,9 +189,11 @@ func (s Role) RemoveGrants(ctx context.Context, grants []string) (*Role, *api.Er
|
||||
// We assume that the client provided has the org and optionally the project id of the request.
|
||||
|
||||
body := map[string]interface{}{
|
||||
"grants": grants,
|
||||
"version": s.Version,
|
||||
}
|
||||
if len(grants) > 0 {
|
||||
body["grants"] = grants
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("roles/%s:remove-grants", s.Id), body)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// Code generated by "make api"; DO NOT EDIT.
|
||||
package roles
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/api/internal/strutil"
|
||||
)
|
||||
|
||||
type Principal struct {
|
||||
Client *api.Client `json:"-"`
|
||||
|
||||
defaultFields []string
|
||||
|
||||
// The ID of the principal.
|
||||
// Output only.
|
||||
Id string `json:"id,omitempty"`
|
||||
// The type of the principal.
|
||||
// Output only.
|
||||
Type string `json:"type,omitempty"`
|
||||
// The scope ID of the principal.
|
||||
// Output only.
|
||||
ScopeId string `json:"scope_id,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Principal) SetDefault(key string) {
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"id": "id", "scopeid": "scope_id", "type": "type"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Principal) UnsetDefault(key string) {
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"id": "id", "scopeid": "scope_id", "type": "type"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Principal) MarshalJSON() ([]byte, error) {
|
||||
m := structs.Map(s)
|
||||
if m == nil {
|
||||
m = make(map[string]interface{})
|
||||
}
|
||||
for _, k := range s.defaultFields {
|
||||
m[k] = nil
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+23
-7
@@ -3,6 +3,7 @@ package roles
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -40,13 +41,14 @@ type Role struct {
|
||||
// The version can be used in subsiquent write requests to ensure this resource
|
||||
// has not changed and to fail the write if it has.
|
||||
// Output only.
|
||||
Version *uint32 `json:"version,omitempty"`
|
||||
// The principals that are assigned this role.
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
// The IDs (only) of principals that are assigned to this role.
|
||||
// Output only.
|
||||
UserIds []string `json:"user_ids,omitempty"`
|
||||
PrincipalIds []string `json:"principal_ids,omitempty"`
|
||||
// The principals that are assigned to this role.
|
||||
// Output only.
|
||||
GroupIds []string `json:"group_ids,omitempty"`
|
||||
// The grants that this role provides for it's principals.
|
||||
Principals []*Principal `json:"principals,omitempty"`
|
||||
// The grants that this role provides for its principals.
|
||||
// Output only.
|
||||
Grants []string `json:"grants,omitempty"`
|
||||
// The canonical version of the grants in the grants field with the same index.
|
||||
@@ -58,11 +60,25 @@ type Role struct {
|
||||
}
|
||||
|
||||
func (s *Role) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "grants": "grants", "grantscanonical": "grants_canonical", "grantscopeid": "grant_scope_id", "grantsjson": "grants_json", "id": "id", "name": "name", "principalids": "principal_ids", "principals": "principals", "updatedtime": "updated_time", "version": "version"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Role) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "grants": "grants", "grantscanonical": "grants_canonical", "grantscopeid": "grant_scope_id", "grantsjson": "grants_json", "id": "id", "name": "name", "principalids": "principal_ids", "principals": "principals", "updatedtime": "updated_time", "version": "version"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Role) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+86
-56
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/strutil"
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/api/groups"
|
||||
"github.com/hashicorp/watchtower/api/roles"
|
||||
@@ -27,7 +28,7 @@ type roleCrud interface {
|
||||
}
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
tc := controller.NewTestController(t, nil)
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{DisableAuthorizationFailures: true})
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
@@ -56,6 +57,22 @@ func TestCustom(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
hasPrincipal := func(role *roles.Role, principalId string) bool {
|
||||
var foundInPrincipals bool
|
||||
var foundInPrincipalIds bool
|
||||
for _, v := range role.Principals {
|
||||
if v.Id == principalId {
|
||||
foundInPrincipals = true
|
||||
}
|
||||
}
|
||||
for _, v := range role.PrincipalIds {
|
||||
if v == principalId {
|
||||
foundInPrincipalIds = true
|
||||
}
|
||||
}
|
||||
return foundInPrincipals && foundInPrincipalIds
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
@@ -70,63 +87,52 @@ func TestCustom(t *testing.T) {
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(r)
|
||||
|
||||
updatedRole, apiErr, err := r.AddPrincipals(ctx, []string{g.Id}, nil)
|
||||
updatedRole, apiErr, err := r.AddPrincipals(ctx, []string{g.Id})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
|
||||
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
|
||||
assert.Contains(t, updatedRole.GroupIds, g.Id)
|
||||
assert.Empty(t, updatedRole.UserIds)
|
||||
require.Nil(apiErr, "Got error ", apiErr)
|
||||
assert.Equal(t, updatedRole.Version, r.Version+1)
|
||||
assert.True(t, hasPrincipal(updatedRole, g.Id))
|
||||
|
||||
r = updatedRole
|
||||
updatedRole, apiErr, err = r.SetPrincipals(ctx, nil, []string{user.Id})
|
||||
updatedRole, apiErr, err = r.SetPrincipals(ctx, []string{user.Id})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
|
||||
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
|
||||
assert.Empty(t, updatedRole.GroupIds)
|
||||
assert.Contains(t, updatedRole.UserIds, user.Id)
|
||||
require.Nil(apiErr, "Got error ", apiErr)
|
||||
assert.Equal(t, updatedRole.Version, r.Version+1)
|
||||
assert.True(t, hasPrincipal(updatedRole, user.Id))
|
||||
|
||||
r = updatedRole
|
||||
updatedRole, apiErr, err = r.RemovePrincipals(ctx, nil, []string{user.Id})
|
||||
updatedRole, apiErr, err = r.RemovePrincipals(ctx, []string{user.Id})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
|
||||
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
|
||||
assert.Empty(t, updatedRole.GroupIds)
|
||||
assert.Empty(t, updatedRole.UserIds)
|
||||
require.Nil(apiErr, "Got error ", apiErr)
|
||||
assert.Equal(t, updatedRole.Version, r.Version+1)
|
||||
assert.Empty(t, updatedRole.Principals)
|
||||
|
||||
r = updatedRole
|
||||
updatedRole, apiErr, err = r.AddGrants(ctx, []string{"id=*;actions=read"})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
|
||||
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
|
||||
require.Nil(apiErr, "Got error ", apiErr)
|
||||
assert.Equal(t, updatedRole.Version, r.Version+1)
|
||||
assert.Contains(t, updatedRole.Grants, "id=*;actions=read")
|
||||
|
||||
r = updatedRole
|
||||
updatedRole, apiErr, err = r.SetGrants(ctx, []string{"id=*;actions=*"})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
|
||||
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
|
||||
require.Nil(apiErr, "Got error ", apiErr)
|
||||
assert.Equal(t, updatedRole.Version, r.Version+1)
|
||||
assert.Contains(t, updatedRole.Grants, "id=*;actions=*")
|
||||
|
||||
r = updatedRole
|
||||
updatedRole, apiErr, err = r.RemoveGrants(ctx, []string{"id=*;actions=*"})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, "Got error ", errorMessage(apiErr))
|
||||
assert.Equal(t, *updatedRole.Version, (*r.Version)+1)
|
||||
require.Nil(apiErr, "Got error ", apiErr)
|
||||
assert.Equal(t, updatedRole.Version, r.Version+1)
|
||||
assert.Empty(t, updatedRole.Grants)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func errorMessage(in *api.Error) string {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
return *in.Message
|
||||
}
|
||||
|
||||
func TestRole_List(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{DisableAuthorizationFailures: true})
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
@@ -153,12 +159,19 @@ func TestRole_List(t *testing.T) {
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
ctx := context.Background()
|
||||
|
||||
pl, apiErr, err := tc.scope.ListRoles(ctx)
|
||||
assert.NoError(err)
|
||||
p1, apiErr, err := tc.scope.ListRoles(ctx)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.Empty(pl)
|
||||
var defaultRoleIds []string
|
||||
if tc.name == "org" {
|
||||
require.True(2 == len(p1))
|
||||
defaultRoleIds = []string{p1[0].Id, p1[1].Id}
|
||||
} else {
|
||||
require.Empty(p1)
|
||||
}
|
||||
|
||||
var expected []*roles.Role
|
||||
for i := 0; i < 10; i++ {
|
||||
@@ -166,21 +179,35 @@ func TestRole_List(t *testing.T) {
|
||||
}
|
||||
|
||||
expected[0], apiErr, err = tc.scope.CreateRole(ctx, expected[0])
|
||||
assert.NoError(err)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
|
||||
pl, apiErr, err = tc.scope.ListRoles(ctx)
|
||||
p2, apiErr, err := tc.scope.ListRoles(ctx)
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(pl))
|
||||
var p2ForComparison []*roles.Role
|
||||
for _, v := range p2 {
|
||||
if !strutil.StrListContains(defaultRoleIds, v.Id) {
|
||||
p2ForComparison = append(p2ForComparison, v)
|
||||
}
|
||||
}
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(p2ForComparison))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
expected[i], apiErr, err = tc.scope.CreateRole(ctx, expected[i])
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
}
|
||||
pl, apiErr, err = tc.scope.ListRoles(ctx)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(pl))
|
||||
p3, apiErr, err := tc.scope.ListRoles(ctx)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
var p3ForComparison []*roles.Role
|
||||
for _, v := range p3 {
|
||||
if !strutil.StrListContains(defaultRoleIds, v.Id) {
|
||||
p3ForComparison = append(p3ForComparison, v)
|
||||
}
|
||||
}
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(p3ForComparison))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -202,7 +229,7 @@ func comparableSlice(in []*roles.Role) []roles.Role {
|
||||
}
|
||||
|
||||
func TestRole_Crud(t *testing.T) {
|
||||
tc := controller.NewTestController(t, nil)
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{DisableAuthorizationFailures: true})
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
@@ -217,8 +244,8 @@ func TestRole_Crud(t *testing.T) {
|
||||
checkRole := func(step string, g *roles.Role, apiErr *api.Error, err error, wantedName string) {
|
||||
assert := assert.New(t)
|
||||
assert.NoError(err, step)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != nil {
|
||||
t.Errorf("ApiError message: %q", *apiErr.Message)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != "" {
|
||||
t.Errorf("ApiError message: %q", apiErr.Message)
|
||||
}
|
||||
assert.NotNil(g, "returned no resource", step)
|
||||
gotName := ""
|
||||
@@ -244,6 +271,7 @@ func TestRole_Crud(t *testing.T) {
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
g, apiErr, err := tt.scope.CreateRole(tc.Context(), &roles.Role{Name: api.String("foo")})
|
||||
checkRole("create", g, apiErr, err, "foo")
|
||||
|
||||
@@ -261,19 +289,20 @@ func TestRole_Crud(t *testing.T) {
|
||||
checkRole("update", g, apiErr, err, "")
|
||||
|
||||
existed, apiErr, err := tt.scope.DeleteRole(tc.Context(), g)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, existed, "Expected existing user when deleted, but it wasn't.")
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.True(existed, "Expected existing user when deleted, but it wasn't.")
|
||||
|
||||
existed, apiErr, err = tt.scope.DeleteRole(tc.Context(), g)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, existed, "Expected user to not exist when deleted, but it did.")
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.False(existed, "Expected user to not exist when deleted, but it did.")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRole_Errors(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{DisableAuthorizationFailures: true})
|
||||
defer tc.Shutdown()
|
||||
ctx := tc.Context()
|
||||
|
||||
@@ -302,30 +331,31 @@ func TestRole_Errors(t *testing.T) {
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
u, apiErr, err := tt.scope.CreateRole(ctx, &roles.Role{Name: api.String("first")})
|
||||
assert.NoError(err)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(u)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, apiErr, err = tt.scope.CreateRole(ctx, &roles.Role{Name: api.String("first")})
|
||||
assert.NoError(err)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, apiErr, err = tt.scope.ReadRole(ctx, &roles.Role{Id: iam.RolePrefix + "_doesntexis"})
|
||||
assert.NoError(err)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusNotFound)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, apiErr, err = tt.scope.ReadRole(ctx, &roles.Role{Id: "invalid id"})
|
||||
assert.NoError(err)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
_, apiErr, err = tt.scope.UpdateRole(ctx, &roles.Role{Id: u.Id})
|
||||
assert.NoError(err)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package scopes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/api/authtokens"
|
||||
)
|
||||
|
||||
// TODO: This will need to be changed when we add Auth Method API to watchtower. We'll also need a better
|
||||
// way to handle different auth method types.
|
||||
func (s Org) Authenticate(ctx context.Context, authMethodId, name, password string) (*authtokens.AuthToken, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in Authenticate request")
|
||||
}
|
||||
if s.Id == "" {
|
||||
// Assume the client has been configured with org already and
|
||||
// move on
|
||||
} else {
|
||||
// If it's explicitly set here, override anything that might be in the
|
||||
// client
|
||||
ctx = context.WithValue(ctx, "org", s.Id)
|
||||
}
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"credentials": map[string]string{
|
||||
"name": name,
|
||||
"password": password,
|
||||
},
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "POST", fmt.Sprintf("auth-methods/%s:authenticate", authMethodId), reqBody)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Authenticate request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := s.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error performing client request during Authenticate call: %w", err)
|
||||
}
|
||||
|
||||
target := new(authtokens.AuthToken)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Authenticate response: %w", err)
|
||||
}
|
||||
|
||||
if target.Token != "" {
|
||||
s.Client.SetToken(target.Token)
|
||||
}
|
||||
|
||||
return target, apiErr, nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package scopes_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/watchtower/api/scopes"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAuthenticate(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := &scopes.Org{
|
||||
Client: client,
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
tok, apiErr, err := org.Authenticate(ctx, "am_anything", "admin", "hunter2")
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(tok)
|
||||
|
||||
_, apiErr, err = org.Authenticate(ctx, "am_anything", "wrong", "wrong")
|
||||
assert.NoError(err)
|
||||
require.NotNil(t, apiErr)
|
||||
assert.EqualValuesf(http.StatusUnauthorized, apiErr.Status, "Expected unauthenticated, got %q", apiErr.Message)
|
||||
}
|
||||
+17
-2
@@ -3,6 +3,7 @@ package scopes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -32,11 +33,25 @@ type Org struct {
|
||||
}
|
||||
|
||||
func (s *Org) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Org) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Org) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package scopes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -34,11 +35,25 @@ type Project struct {
|
||||
}
|
||||
|
||||
func (s *Project) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Project) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Project) MarshalJSON() ([]byte, error) {
|
||||
|
||||
@@ -133,10 +133,10 @@ func TestProject_Errors(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
// TODO: Should this be nil instead of just a Project that has no values set
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusNotFound)
|
||||
assert.EqualValues(apiErr.Status, http.StatusNotFound)
|
||||
|
||||
_, apiErr, err = org.ReadProject(ctx, &scopes.Project{Id: "invalid id"})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
}
|
||||
+41
-41
@@ -177,47 +177,6 @@ func (s Org) ReadUser(ctx context.Context, r *users.User) (*users.User, *api.Err
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (s Project) ReadHostCatalog(ctx context.Context, r *hosts.HostCatalog) (*hosts.HostCatalog, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in ReadHostCatalog request")
|
||||
}
|
||||
if s.Id == "" {
|
||||
|
||||
// Assume the client has been configured with project already and move
|
||||
// on
|
||||
|
||||
} else {
|
||||
// If it's explicitly set here, override anything that might be in the
|
||||
// client
|
||||
|
||||
ctx = context.WithValue(ctx, "project", s.Id)
|
||||
|
||||
}
|
||||
if r.Id == "" {
|
||||
return nil, nil, fmt.Errorf("empty hosts.HostCatalog ID field in ReadHostCatalog request")
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "GET", fmt.Sprintf("%s/%s", "host-catalogs", r.Id), r)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating ReadHostCatalog request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := s.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error performing client request during ReadHostCatalog call: %w", err)
|
||||
}
|
||||
|
||||
target := new(hosts.HostCatalog)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding ReadHostCatalog repsonse: %w", err)
|
||||
}
|
||||
|
||||
target.Client = s.Client
|
||||
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (s Project) ReadGroup(ctx context.Context, r *groups.Group) (*groups.Group, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in ReadGroup request")
|
||||
@@ -299,3 +258,44 @@ func (s Project) ReadRole(ctx context.Context, r *roles.Role) (*roles.Role, *api
|
||||
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (s Project) ReadHostCatalog(ctx context.Context, r *hosts.HostCatalog) (*hosts.HostCatalog, *api.Error, error) {
|
||||
if s.Client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in ReadHostCatalog request")
|
||||
}
|
||||
if s.Id == "" {
|
||||
|
||||
// Assume the client has been configured with project already and move
|
||||
// on
|
||||
|
||||
} else {
|
||||
// If it's explicitly set here, override anything that might be in the
|
||||
// client
|
||||
|
||||
ctx = context.WithValue(ctx, "project", s.Id)
|
||||
|
||||
}
|
||||
if r.Id == "" {
|
||||
return nil, nil, fmt.Errorf("empty hosts.HostCatalog ID field in ReadHostCatalog request")
|
||||
}
|
||||
|
||||
req, err := s.Client.NewRequest(ctx, "GET", fmt.Sprintf("%s/%s", "host-catalogs", r.Id), r)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating ReadHostCatalog request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := s.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error performing client request during ReadHostCatalog call: %w", err)
|
||||
}
|
||||
|
||||
target := new(hosts.HostCatalog)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding ReadHostCatalog repsonse: %w", err)
|
||||
}
|
||||
|
||||
target.Client = s.Client
|
||||
|
||||
return target, apiErr, nil
|
||||
}
|
||||
+17
-2
@@ -3,6 +3,7 @@ package users
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
@@ -34,11 +35,25 @@ type User struct {
|
||||
}
|
||||
|
||||
func (s *User) SetDefault(key string) {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.AppendIfMissing(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *User) UnsetDefault(key string) {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, key)
|
||||
lowerKey := strings.ToLower(key)
|
||||
validMap := map[string]string{"createdtime": "created_time", "description": "description", "disabled": "disabled", "id": "id", "name": "name", "updatedtime": "updated_time"}
|
||||
for k, v := range validMap {
|
||||
if k == lowerKey || v == lowerKey {
|
||||
s.defaultFields = strutil.StrListDelete(s.defaultFields, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s User) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+13
-8
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/iam"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUsers_List(t *testing.T) {
|
||||
@@ -50,6 +51,8 @@ func TestUsers_List(t *testing.T) {
|
||||
assert.Nil(apiErr)
|
||||
}
|
||||
ul, apiErr, err = org.ListUsers(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(ul))
|
||||
}
|
||||
|
||||
@@ -81,8 +84,8 @@ func TestUser_Crud(t *testing.T) {
|
||||
checkUser := func(step string, u *users.User, apiErr *api.Error, err error, wantedName string) {
|
||||
assert := assert.New(t)
|
||||
assert.NoError(err, step)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != nil {
|
||||
t.Errorf("ApiError message: %q", *apiErr.Message)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != "" {
|
||||
t.Errorf("ApiError message: %q", apiErr.Message)
|
||||
}
|
||||
assert.NotNil(u, "returned no resource", step)
|
||||
gotName := ""
|
||||
@@ -108,12 +111,14 @@ func TestUser_Crud(t *testing.T) {
|
||||
u, apiErr, err = org.UpdateUser(tc.Context(), u)
|
||||
checkUser("update", u, apiErr, err, "")
|
||||
|
||||
existed, apiErr, err := org.DeleteUser(tc.Context(), u)
|
||||
assert.NoError(t, err)
|
||||
existed, _, err := org.DeleteUser(tc.Context(), u)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, apiErr)
|
||||
assert.True(t, existed, "Expected existing user when deleted, but it wasn't.")
|
||||
|
||||
existed, apiErr, err = org.DeleteUser(tc.Context(), u)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, apiErr)
|
||||
assert.False(t, existed, "Expected user to not exist when deleted, but it did.")
|
||||
}
|
||||
|
||||
@@ -141,15 +146,15 @@ func TestUser_Errors(t *testing.T) {
|
||||
_, apiErr, err = org.ReadUser(ctx, &users.User{Id: iam.UserPrefix + "_doesntexis"})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusNotFound)
|
||||
assert.EqualValues(apiErr.Status, http.StatusNotFound)
|
||||
|
||||
_, apiErr, err = org.ReadUser(ctx, &users.User{Id: "invalid id"})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
|
||||
_, apiErr, err = org.UpdateUser(ctx, &users.User{Id: u.Id})
|
||||
assert.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(*apiErr.Status, http.StatusBadRequest)
|
||||
assert.EqualValues(apiErr.Status, http.StatusBadRequest)
|
||||
}
|
||||
@@ -9,6 +9,10 @@ import "time"
|
||||
// import issues. These values should only ever be set at startup, but simply
|
||||
// available to reference from anywhere.
|
||||
|
||||
const (
|
||||
ContextUserIdValue = "wt_user_id"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultMaxRequestDuration is the amount of time we'll wait for a request
|
||||
DefaultMaxRequestDuration = 90 * time.Second
|
||||
|
||||
@@ -17,6 +17,7 @@ require (
|
||||
github.com/go-openapi/swag v0.19.9 // indirect
|
||||
github.com/go-openapi/validate v0.19.8 // indirect
|
||||
github.com/go-swagger/go-swagger v0.23.0
|
||||
github.com/go-test/deep v1.0.3 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.11.0
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe
|
||||
github.com/golang/protobuf v1.4.2
|
||||
@@ -29,6 +30,7 @@ require (
|
||||
github.com/hashicorp/go-hclog v0.14.1
|
||||
github.com/hashicorp/go-kms-wrapping v0.5.10
|
||||
github.com/hashicorp/go-multierror v1.1.0
|
||||
github.com/hashicorp/go-plugin v1.2.0 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6
|
||||
github.com/hashicorp/go-rootcerts v1.0.2
|
||||
github.com/hashicorp/go-sockaddr v1.0.2
|
||||
@@ -44,6 +46,7 @@ require (
|
||||
github.com/mattn/go-colorable v0.1.6
|
||||
github.com/mitchellh/cli v1.1.1
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/go-wordwrap v1.0.0
|
||||
github.com/mitchellh/gox v1.0.1
|
||||
github.com/mitchellh/mapstructure v1.3.2
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
@@ -57,7 +60,9 @@ require (
|
||||
github.com/ryanuber/go-glob v1.0.0
|
||||
github.com/spf13/viper v1.6.3 // indirect
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/zalando/go-keyring v0.1.0
|
||||
go.mongodb.org/mongo-driver v1.3.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
|
||||
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 // indirect
|
||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f // indirect
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
|
||||
|
||||
@@ -248,6 +248,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
|
||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU=
|
||||
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -430,6 +432,8 @@ github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
|
||||
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
@@ -469,6 +473,8 @@ github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY9
|
||||
github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df h1:fwXmhM0OqixzJDOGgTSyNH9eEDij9uGTXwsyWXvyR0A=
|
||||
github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
|
||||
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
@@ -639,6 +645,8 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+
|
||||
github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
|
||||
github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE=
|
||||
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
|
||||
github.com/hashicorp/go-plugin v1.2.0 h1:CUfYokW0EJNDcGecVrHZK//Cp1GFlHwoqtcUIEiU6BY=
|
||||
github.com/hashicorp/go-plugin v1.2.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
|
||||
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4=
|
||||
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
@@ -837,6 +845,7 @@ github.com/jefferai/jsonx v1.0.0 h1:Xoz0ZbmkpBvED5W9W1B5B/zc3Oiq7oXqiW7iRV3B6EI=
|
||||
github.com/jefferai/jsonx v1.0.0/go.mod h1:OGmqmi2tTeI/PS+qQfBDToLHHJIy/RMp24fPo8vFvoQ=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
||||
github.com/jhump/protoreflect v1.6.2-0.20200602154950-9a9113f80b57 h1:DDbkVWVTpzxHbD80e2zpbczB+gkTWI1w2gSeL+viRhc=
|
||||
github.com/jhump/protoreflect v1.6.2-0.20200602154950-9a9113f80b57/go.mod h1:RZkzh7Hi9J7qT/sPlWnJ/UwZqCJvciFxKDA0UCeltSM=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
@@ -982,6 +991,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
|
||||
@@ -1256,6 +1266,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zalando/go-keyring v0.1.0 h1:ffq972Aoa4iHNzBlUHgK5Y+k8+r/8GvcGd80/OFZb/k=
|
||||
github.com/zalando/go-keyring v0.1.0/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
@@ -1367,6 +1379,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180801234040-f4c29de78a2a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/posener/complete"
|
||||
"github.com/zalando/go-keyring"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,6 +27,8 @@ const (
|
||||
|
||||
// NotSetValue is a flag value for a not-set value
|
||||
NotSetValue = "(not set)"
|
||||
|
||||
envTokenName = "WATCHTOWER_TOKEN_NAME"
|
||||
)
|
||||
|
||||
// reRemoveWhitespace is a regular expression for stripping whitespace from
|
||||
@@ -53,6 +56,7 @@ type Command struct {
|
||||
|
||||
flagFormat string
|
||||
flagField string
|
||||
FlagTokenName string
|
||||
flagOutputCurlString bool
|
||||
|
||||
client *api.Client
|
||||
@@ -161,6 +165,26 @@ func (c *Command) Client() (*api.Client, error) {
|
||||
c.client.SetMaxRetries(0)
|
||||
}
|
||||
|
||||
if c.client.Token() == "" {
|
||||
tokenName := "default"
|
||||
if c.FlagTokenName != "" {
|
||||
tokenName = c.FlagTokenName
|
||||
}
|
||||
if tokenName != "none" {
|
||||
token, err := keyring.Get("HashiCorp Watchtower Auth Token", tokenName)
|
||||
if err != nil {
|
||||
if err == keyring.ErrNotFound {
|
||||
c.UI.Info("No saved credential found, continuing without")
|
||||
} else {
|
||||
c.UI.Error(fmt.Sprintf("Error reading auth token from system credential store: %s", err))
|
||||
}
|
||||
}
|
||||
if token != "" {
|
||||
c.client.SetToken(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
@@ -169,6 +193,7 @@ type FlagSetBit uint
|
||||
const (
|
||||
FlagSetNone FlagSetBit = 1 << iota
|
||||
FlagSetHTTP
|
||||
FlagSetClient
|
||||
FlagSetOutputField
|
||||
FlagSetOutputFormat
|
||||
)
|
||||
@@ -274,6 +299,17 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
|
||||
"is highly discouraged as it decreases the security of data " +
|
||||
"transmissions to and from the Watchtower server.",
|
||||
})
|
||||
}
|
||||
|
||||
if bit&FlagSetClient != 0 {
|
||||
f := set.NewFlagSet("Client Options")
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: "token-name",
|
||||
Target: &c.FlagTokenName,
|
||||
EnvVar: envTokenName,
|
||||
Usage: "If specified, the given value will be used as the name when storing the token in the system credential store. This can allow switching user identities for different commands.",
|
||||
})
|
||||
|
||||
f.BoolVar(&BoolVar{
|
||||
Name: "output-curl-string",
|
||||
|
||||
@@ -3,11 +3,15 @@ package base
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
@@ -17,6 +21,39 @@ const (
|
||||
hopeDelim = "♨"
|
||||
)
|
||||
|
||||
// This is adapted from the code in the strings package for TrimSpace
|
||||
var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
|
||||
|
||||
func trimSpaceRight(in string) string {
|
||||
for stop := len(in); stop > 0; stop-- {
|
||||
c := in[stop-1]
|
||||
if c >= utf8.RuneSelf {
|
||||
return strings.TrimFunc(in[:stop], unicode.IsSpace)
|
||||
}
|
||||
if asciiSpace[c] == 0 {
|
||||
return in[0:stop]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func WrapForHelpText(lines []string) string {
|
||||
var ret []string
|
||||
for _, line := range lines {
|
||||
line = trimSpaceRight(line)
|
||||
trimmed := strings.TrimSpace(line)
|
||||
diff := uint(len(line) - len(trimmed))
|
||||
wrapped := wordwrap.WrapString(trimmed, TermWidth-diff)
|
||||
splitWrapped := strings.Split(wrapped, "\n")
|
||||
for i := range splitWrapped {
|
||||
splitWrapped[i] = fmt.Sprintf("%s%s", strings.Repeat(" ", int(diff)), strings.TrimSpace(splitWrapped[i]))
|
||||
}
|
||||
ret = append(ret, strings.Join(splitWrapped, "\n"))
|
||||
}
|
||||
|
||||
return strings.Join(ret, "\n")
|
||||
}
|
||||
|
||||
type FormatOptions struct {
|
||||
Format string
|
||||
}
|
||||
@@ -25,7 +62,7 @@ type FormatOptions struct {
|
||||
type JsonFormatter struct{}
|
||||
|
||||
func (j JsonFormatter) Format(data interface{}) ([]byte, error) {
|
||||
return json.MarshalIndent(data, "", " ")
|
||||
return json.Marshal(data)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -346,3 +383,29 @@ func looksLikeDuration(k string) bool {
|
||||
k == "duration" || strings.HasSuffix(k, "_duration") ||
|
||||
k == "lease_max" || k == "ttl_max"
|
||||
}
|
||||
|
||||
type Formatter interface {
|
||||
//Output(ui cli.Ui, secret *api.Secret, data interface{}) error
|
||||
Format(data interface{}) ([]byte, error)
|
||||
}
|
||||
|
||||
var Formatters = map[string]Formatter{
|
||||
"json": JsonFormatter{},
|
||||
"table": TableFormatter{},
|
||||
"yaml": YamlFormatter{},
|
||||
"yml": YamlFormatter{},
|
||||
}
|
||||
|
||||
func Format(ui cli.Ui) string {
|
||||
switch ui.(type) {
|
||||
case *WatchtowerUI:
|
||||
return ui.(*WatchtowerUI).Format
|
||||
}
|
||||
|
||||
format := os.Getenv(EnvWatchtowerCLIFormat)
|
||||
if format == "" {
|
||||
format = "table"
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/hashicorp/watchtower/globals"
|
||||
"github.com/hashicorp/watchtower/internal/db"
|
||||
"github.com/hashicorp/watchtower/internal/iam"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/authenticate"
|
||||
"github.com/hashicorp/watchtower/version"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/mitchellh/cli"
|
||||
@@ -59,7 +60,8 @@ type Server struct {
|
||||
|
||||
Listeners []*ServerListener
|
||||
|
||||
DefaultOrgId string
|
||||
DefaultOrgId string
|
||||
DevAuthMethodId string
|
||||
|
||||
DevDatabaseUrl string
|
||||
DevDatabaseCleanupFunc func() error
|
||||
@@ -418,40 +420,86 @@ func (b *Server) CreateDevDatabase(dialect string) error {
|
||||
cancel()
|
||||
}()
|
||||
|
||||
var scope *iam.Scope
|
||||
var orgScope *iam.Scope
|
||||
if b.DefaultOrgId != "" {
|
||||
scope, err = repo.LookupScope(ctx, b.DefaultOrgId)
|
||||
orgScope, err = repo.LookupScope(ctx, b.DefaultOrgId)
|
||||
if err != nil {
|
||||
c()
|
||||
return fmt.Errorf("error looking up existing scope with org ID %q: %w", b.DefaultOrgId, err)
|
||||
}
|
||||
if scope != nil {
|
||||
goto INFO
|
||||
}
|
||||
}
|
||||
|
||||
scope, err = iam.NewOrg()
|
||||
if err != nil {
|
||||
c()
|
||||
return fmt.Errorf("error creating new org scope: %w", err)
|
||||
}
|
||||
scope, err = repo.CreateScope(ctx, scope, iam.WithPublicId(b.DefaultOrgId))
|
||||
if err != nil {
|
||||
c()
|
||||
return fmt.Errorf("error persisting new org scope: %w", err)
|
||||
}
|
||||
if b.DefaultOrgId != "" {
|
||||
if scope.GetPublicId() != b.DefaultOrgId {
|
||||
if orgScope == nil {
|
||||
orgScope, err = iam.NewOrg()
|
||||
if err != nil {
|
||||
c()
|
||||
return fmt.Errorf("expected org ID %q, got %q after persisting", b.DefaultOrgId, scope.GetPublicId())
|
||||
return fmt.Errorf("error creating new org scope: %w", err)
|
||||
}
|
||||
orgScope, err = repo.CreateScope(ctx, orgScope, iam.WithPublicId(b.DefaultOrgId))
|
||||
if err != nil {
|
||||
c()
|
||||
return fmt.Errorf("error persisting new org scope: %w", err)
|
||||
}
|
||||
if b.DefaultOrgId != "" {
|
||||
if orgScope.GetPublicId() != b.DefaultOrgId {
|
||||
c()
|
||||
return fmt.Errorf("expected org ID %q, got %q after persisting", b.DefaultOrgId, orgScope.GetPublicId())
|
||||
}
|
||||
} else {
|
||||
b.DefaultOrgId = orgScope.GetPublicId()
|
||||
}
|
||||
} else {
|
||||
b.DefaultOrgId = scope.GetPublicId()
|
||||
}
|
||||
|
||||
INFO:
|
||||
b.InfoKeys = append(b.InfoKeys, "dev org id")
|
||||
ar, err := iam.NewRole(orgScope.PublicId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating in memory role for anon authen: %w", err)
|
||||
}
|
||||
authenRole, err := repo.CreateRole(ctx, ar, iam.WithDescription("role for anon authen"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating role for anon authen: %w", err)
|
||||
}
|
||||
if _, err := repo.AddRoleGrants(ctx, authenRole.PublicId, authenRole.Version, []string{"type=auth-method;actions=list,authenticate"}); err != nil {
|
||||
return fmt.Errorf("error creating grant for anon authen: %w", err)
|
||||
}
|
||||
if _, err := repo.AddPrincipalRoles(ctx, authenRole.PublicId, authenRole.Version+1, []string{"u_anon"}, nil); err != nil {
|
||||
return fmt.Errorf("error adding principal to role for anon authen: %w", err)
|
||||
}
|
||||
|
||||
pr, err := iam.NewRole(orgScope.PublicId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating in memory role for default dev grants: %w", err)
|
||||
}
|
||||
defPermsRole, err := repo.CreateRole(ctx, pr, iam.WithDescription("role for def grants"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating role for default dev grants: %w", err)
|
||||
}
|
||||
if _, err := repo.AddRoleGrants(ctx, defPermsRole.PublicId, defPermsRole.Version, []string{"id=*;actions=*"}); err != nil {
|
||||
return fmt.Errorf("error creating grant for default dev grants: %w", err)
|
||||
}
|
||||
if _, err := repo.AddPrincipalRoles(ctx, defPermsRole.PublicId, defPermsRole.Version+1, []string{"u_auth"}, nil); err != nil {
|
||||
return fmt.Errorf("error adding principal to role for default dev grants: %w", err)
|
||||
}
|
||||
|
||||
// TODO: Remove this when Auth Account repo is in place.
|
||||
authenticate.OrgScope = orgScope.GetPublicId()
|
||||
insert := `insert into auth_method
|
||||
(public_id, scope_id)
|
||||
values
|
||||
($1, $2);`
|
||||
amId := b.DevAuthMethodId
|
||||
if amId == "" {
|
||||
amId = "am_1234567890"
|
||||
}
|
||||
authenticate.RWDb.Store(rw)
|
||||
_, err = b.Database.DB().Exec(insert, amId, orgScope.GetPublicId())
|
||||
if err != nil {
|
||||
c()
|
||||
return err
|
||||
}
|
||||
|
||||
b.InfoKeys = append(b.InfoKeys, "dev org id", "dev auth method id")
|
||||
b.Info["dev org id"] = b.DefaultOrgId
|
||||
b.Info["dev auth method id"] = amId
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
type WatchtowerUI struct {
|
||||
cli.Ui
|
||||
Format string
|
||||
}
|
||||
|
||||
var TermWidth uint = 80
|
||||
|
||||
func init() {
|
||||
width, _, err := terminal.GetSize(int(os.Stdin.Fd()))
|
||||
if err == nil {
|
||||
TermWidth = uint(width)
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,12 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/authenticate"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/config"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/controller"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/dev"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/hosts"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/roles"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/scopes"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/commands/worker"
|
||||
|
||||
@@ -82,6 +84,87 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
|
||||
Command: base.NewCommand(ui),
|
||||
}, nil
|
||||
},
|
||||
"authenticate": func() (cli.Command, error) {
|
||||
return &authenticate.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
}, nil
|
||||
},
|
||||
"authenticate password": func() (cli.Command, error) {
|
||||
return &authenticate.PasswordCommand{
|
||||
Command: base.NewCommand(ui),
|
||||
}, nil
|
||||
},
|
||||
"roles": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
}, nil
|
||||
},
|
||||
"roles create": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "create",
|
||||
}, nil
|
||||
},
|
||||
"roles update": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "update",
|
||||
}, nil
|
||||
},
|
||||
"roles read": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "read",
|
||||
}, nil
|
||||
},
|
||||
"roles delete": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "delete",
|
||||
}, nil
|
||||
},
|
||||
"roles list": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "list",
|
||||
}, nil
|
||||
},
|
||||
"roles add-principals": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "add-principals",
|
||||
}, nil
|
||||
},
|
||||
"roles set-principals": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "set-principals",
|
||||
}, nil
|
||||
},
|
||||
"roles remove-principals": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "remove-principals",
|
||||
}, nil
|
||||
},
|
||||
"roles add-grants": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "add-grants",
|
||||
}, nil
|
||||
},
|
||||
"roles set-grants": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "set-grants",
|
||||
}, nil
|
||||
},
|
||||
"roles remove-grants": func() (cli.Command, error) {
|
||||
return &roles.Command{
|
||||
Command: base.NewCommand(ui),
|
||||
Func: "remove-grants",
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package authenticate
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
)
|
||||
|
||||
var _ cli.Command = (*Command)(nil)
|
||||
|
||||
type Command struct {
|
||||
*base.Command
|
||||
}
|
||||
|
||||
func (c *Command) Synopsis() string {
|
||||
return wordwrap.WrapString("Authenticate the Watchtower commandline client", base.TermWidth)
|
||||
}
|
||||
|
||||
func (c *Command) Help() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower authenticate [sub command] [options] [args]",
|
||||
"",
|
||||
" This command authenticates the Watchtower commandline client using a specified auth method. Examples:",
|
||||
"",
|
||||
" Authenticate with password auth method:",
|
||||
"",
|
||||
" $ watchtower authenticate password -name foo -password bar",
|
||||
"",
|
||||
" Please see the auth method subcommand help for detailed usage information.",
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Command) Run(args []string) int {
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package authenticate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/password"
|
||||
"github.com/hashicorp/watchtower/api/scopes"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/kr/pretty"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
"github.com/posener/complete"
|
||||
"github.com/zalando/go-keyring"
|
||||
)
|
||||
|
||||
var _ cli.Command = (*PasswordCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*PasswordCommand)(nil)
|
||||
|
||||
var envPassword = "WATCHTOWER_AUTHENTICATE_PASSWORD"
|
||||
var envName = "WATCHTOWER_AUTHENTICATE_NAME"
|
||||
var envMethodId = "WATCHTOWER_AUTHENTICATE_METHOD_ID"
|
||||
|
||||
type PasswordCommand struct {
|
||||
*base.Command
|
||||
|
||||
flagName string
|
||||
flagPassword string
|
||||
flagMethodId string
|
||||
}
|
||||
|
||||
func (c *PasswordCommand) Synopsis() string {
|
||||
return wordwrap.WrapString("Invoke the password auth method to authenticate with Watchtower", base.TermWidth)
|
||||
}
|
||||
|
||||
func (c *PasswordCommand) Help() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower authenticate password [options] [args]",
|
||||
"",
|
||||
" Invoke the password auth method to authenticate the Watchtower CLI:",
|
||||
"",
|
||||
" $ watchtower authenticate password -name=foo -password=bar",
|
||||
"",
|
||||
" If more than one instance of the password auth method exists, use the -method-id flag:",
|
||||
"",
|
||||
` $ watchtower authenticate password -method-id am_12345 -name foo -password "bar"`,
|
||||
}) + c.Flags().Help()
|
||||
}
|
||||
|
||||
func (c *PasswordCommand) Flags() *base.FlagSets {
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetClient | base.FlagSetOutputFormat)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "name",
|
||||
Target: &c.flagName,
|
||||
EnvVar: envName,
|
||||
Usage: "Login name",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "password",
|
||||
Target: &c.flagPassword,
|
||||
EnvVar: envPassword,
|
||||
Usage: "Password",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "method-id",
|
||||
Target: &c.flagMethodId,
|
||||
EnvVar: envMethodId,
|
||||
Usage: "Specify if more than one instance of a password auth method exists in the given org",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *PasswordCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *PasswordCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *PasswordCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
switch {
|
||||
case c.flagName == "":
|
||||
c.UI.Error("Name must be provided via -name")
|
||||
return 1
|
||||
case c.flagMethodId == "":
|
||||
c.UI.Error("Auth method ID must be provided via -method-id")
|
||||
return 1
|
||||
}
|
||||
|
||||
if c.flagPassword == "" {
|
||||
fmt.Print("Password is not set as flag or in env, please enter it now (will be hidden): ")
|
||||
value, err := password.Read(os.Stdin)
|
||||
fmt.Print("\n")
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error()))
|
||||
return 2
|
||||
}
|
||||
c.flagPassword = strings.TrimSpace(value)
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error creating API client: %s", err.Error()))
|
||||
return 2
|
||||
}
|
||||
|
||||
org := &scopes.Org{
|
||||
Client: client,
|
||||
}
|
||||
|
||||
// note: Authenticate() calls SetToken() under the hood to set the
|
||||
// auth bearer on the client so we do not need to do anything with the
|
||||
// returned token after this call, so we ignore it
|
||||
result, apiErr, err := org.Authenticate(c.Context, c.flagMethodId, c.flagName, c.flagPassword)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error trying to perform authentication: %s", err.Error()))
|
||||
return 2
|
||||
}
|
||||
if apiErr != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error from controller when performing authentication: %s", pretty.Sprint(apiErr)))
|
||||
return 1
|
||||
}
|
||||
|
||||
switch base.Format(c.UI) {
|
||||
case "table":
|
||||
c.UI.Output(base.WrapForHelpText([]string{
|
||||
"",
|
||||
"Authentication information:",
|
||||
fmt.Sprintf(" Token: %s", result.Token),
|
||||
fmt.Sprintf(" User ID: %s", result.UserId),
|
||||
fmt.Sprintf(" Expiration Time: %s", result.ExpirationTime.Local().Format(time.RFC3339)),
|
||||
}))
|
||||
}
|
||||
|
||||
tokenName := "default"
|
||||
if c.Command.FlagTokenName != "" {
|
||||
tokenName = c.Command.FlagTokenName
|
||||
}
|
||||
if tokenName != "none" {
|
||||
if err := keyring.Set("HashiCorp Watchtower Auth Token", tokenName, result.Token); err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error saving auth token to system credential store: %s", err))
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -48,6 +48,7 @@ type Command struct {
|
||||
flagDevControllerAPIListenAddr string
|
||||
flagDevControllerClusterListenAddr string
|
||||
flagDevOrgId string
|
||||
flagDevAuthMethodId string
|
||||
flagDevPassthroughDirectory string
|
||||
}
|
||||
|
||||
@@ -119,6 +120,14 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-auth-method-id",
|
||||
Target: &c.flagDevAuthMethodId,
|
||||
EnvVar: "WATCHTWER_DEV_AUTH_METHOD_ID",
|
||||
Usage: "Auto-created auth method ID. This only applies when running in \"dev\" " +
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-admin-password",
|
||||
Target: &c.flagDevAdminPassword,
|
||||
@@ -336,6 +345,18 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
|
||||
if c.flagDevOrgId != "" {
|
||||
c.Config.DefaultOrgId = c.flagDevOrgId
|
||||
}
|
||||
if c.flagDevAuthMethodId != "" {
|
||||
if !strings.HasPrefix(c.flagDevAuthMethodId, "am_") {
|
||||
c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must start with %q", "am_"))
|
||||
return 1
|
||||
}
|
||||
if len(c.flagDevAuthMethodId) != 13 {
|
||||
c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must be 10 base62 characters after %q", "am_"))
|
||||
return 1
|
||||
}
|
||||
c.DevAuthMethodId = c.flagDevAuthMethodId
|
||||
}
|
||||
|
||||
c.Config.PassthroughDirectory = c.flagDevPassthroughDirectory
|
||||
|
||||
for _, l := range c.Config.Listeners {
|
||||
|
||||
@@ -36,6 +36,7 @@ type Command struct {
|
||||
flagDev bool
|
||||
flagDevAdminPassword string
|
||||
flagDevOrgId string
|
||||
flagDevAuthMethodId string
|
||||
flagDevControllerAPIListenAddr string
|
||||
flagDevControllerClusterListenAddr string
|
||||
flagDevPassthroughDirectory string
|
||||
@@ -92,6 +93,14 @@ func (c *Command) Flags() *base.FlagSets {
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-auth-method-id",
|
||||
Target: &c.flagDevAuthMethodId,
|
||||
EnvVar: "WATCHTWER_DEV_AUTH_METHOD_ID",
|
||||
Usage: "Auto-created auth method ID. This only applies when running in \"dev\" " +
|
||||
"mode.",
|
||||
})
|
||||
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "dev-admin-password",
|
||||
Target: &c.flagDevAdminPassword,
|
||||
@@ -155,6 +164,18 @@ func (c *Command) Run(args []string) int {
|
||||
if c.flagDevOrgId != "" {
|
||||
devConfig.DefaultOrgId = c.flagDevOrgId
|
||||
}
|
||||
if c.flagDevAuthMethodId != "" {
|
||||
if !strings.HasPrefix(c.flagDevAuthMethodId, "am_") {
|
||||
c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must start with %q", "am_"))
|
||||
return 1
|
||||
}
|
||||
if len(c.flagDevAuthMethodId) != 13 {
|
||||
c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must be 10 base62 characters after %q", "am_"))
|
||||
return 1
|
||||
}
|
||||
c.DevAuthMethodId = c.flagDevAuthMethodId
|
||||
}
|
||||
|
||||
devConfig.PassthroughDirectory = c.flagDevPassthroughDirectory
|
||||
|
||||
for _, l := range devConfig.Listeners {
|
||||
|
||||
@@ -45,7 +45,7 @@ Usage: watchtower hosts create
|
||||
}
|
||||
|
||||
func (c *CreateCommand) Flags() *base.FlagSets {
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetOutputFormat)
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetClient | base.FlagSetOutputFormat)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/textproto"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/watchtower/api/roles"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
)
|
||||
|
||||
func synopsisFunc(inFunc string) string {
|
||||
if inFunc == "" {
|
||||
return wordwrap.WrapString("Manage Watchtower roles", base.TermWidth)
|
||||
}
|
||||
return wordwrap.WrapString(fmt.Sprintf("%s a role within Watchtower", textproto.CanonicalMIMEHeaderKey(inFunc)), base.TermWidth)
|
||||
}
|
||||
|
||||
func principalsGrantsSynopsisFunc(inFunc string, principals bool) string {
|
||||
var in string
|
||||
switchStr := "principals (users, groups)"
|
||||
if !principals {
|
||||
switchStr = "grants"
|
||||
}
|
||||
switch {
|
||||
case strings.HasPrefix(inFunc, "add"):
|
||||
in = fmt.Sprintf("Add %s to", switchStr)
|
||||
case strings.HasPrefix(inFunc, "set"):
|
||||
in = fmt.Sprintf("Set the full contents of the %s on", switchStr)
|
||||
case strings.HasPrefix(inFunc, "remove"):
|
||||
in = fmt.Sprintf("Remove %s from", switchStr)
|
||||
}
|
||||
return wordwrap.WrapString(fmt.Sprintf("%s a role within Watchtower", in), base.TermWidth)
|
||||
}
|
||||
|
||||
func baseHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles [sub command] [options] [args]",
|
||||
"",
|
||||
" This command allows operations on Watchtower roles. Examples:",
|
||||
"",
|
||||
" Create a role:",
|
||||
"",
|
||||
` $ watchtower roles create -name foo -description "For ProdOps usage"`,
|
||||
"",
|
||||
" Add a grant to a role:",
|
||||
"",
|
||||
` $ watchtower roles add-grants -id r_1234567890 -grant "type=host-catalog;actions=create,delete"`,
|
||||
"",
|
||||
" Please see the role subcommand help for detailed usage information.",
|
||||
})
|
||||
}
|
||||
|
||||
func createHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles create [options] [args]",
|
||||
"",
|
||||
" Create a role. Example:",
|
||||
"",
|
||||
` $ watchtower roles create -name ops -description "Role for ops grants"`,
|
||||
"",
|
||||
"",
|
||||
})
|
||||
}
|
||||
|
||||
func updateHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles update [options] [args]",
|
||||
"",
|
||||
" Update a role given its ID. Example:",
|
||||
"",
|
||||
` $ watchtower roles update -id r_1234567890 -description "Development host grants"`,
|
||||
})
|
||||
}
|
||||
|
||||
func readHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles read [options] [args]",
|
||||
"",
|
||||
" Read a role given its ID. Example:",
|
||||
"",
|
||||
` $ watchtower roles read -id r_1234567890`,
|
||||
})
|
||||
}
|
||||
|
||||
func deleteHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles delete [options] [args]",
|
||||
"",
|
||||
" Delete a role given its ID. Example:",
|
||||
"",
|
||||
` $ watchtower roles delete -id r_1234567890`,
|
||||
})
|
||||
}
|
||||
|
||||
func listHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles list [options] [args]",
|
||||
"",
|
||||
" List roles within a scope. Example:",
|
||||
"",
|
||||
` $ watchtower roles list -org o_1234567890`,
|
||||
})
|
||||
}
|
||||
|
||||
func addPrincipalsHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles add-principals [options] [args]",
|
||||
"",
|
||||
` Adds principals (users, groups) to a role given its ID. The "user" and "group" flags can be specified multiple times. Example:`,
|
||||
"",
|
||||
` $ watchtower roles add-principals -id r_1234567890 -user u_1234567890`,
|
||||
})
|
||||
}
|
||||
|
||||
func setPrincipalsHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles set-principals [options] [args]",
|
||||
"",
|
||||
` Sets the complete set of principals (users, groups) on a role given its ID. The "user" and "group" flags can be specified multiple times. Example:`,
|
||||
"",
|
||||
` $ watchtower roles set-principals -id r_1234567890 -user u_anon -group sg_1234567890`,
|
||||
})
|
||||
}
|
||||
|
||||
func removePrincipalsHelp() string {
|
||||
return base.WrapForHelpText([]string{
|
||||
"Usage: watchtower roles remove-principals [options] [args]",
|
||||
"",
|
||||
` Removes principals (users, groups) from a role given its ID. The "user" and "group" flags can be specified multiple times. Example:`,
|
||||
"",
|
||||
` $ watchtower roles remove-principals -id r_1234567890 -group sg_1234567890`,
|
||||
})
|
||||
}
|
||||
|
||||
func populateFlags(c *Command, f *base.FlagSet, flagNames []string) {
|
||||
for _, name := range flagNames {
|
||||
switch name {
|
||||
case "id":
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "id",
|
||||
Target: &c.flagId,
|
||||
Usage: "ID of the role to operate on",
|
||||
})
|
||||
case "name":
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "name",
|
||||
Target: &c.flagName,
|
||||
Usage: "Name to set on the role",
|
||||
})
|
||||
case "description":
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "description",
|
||||
Target: &c.flagDescription,
|
||||
Usage: "Description to set on the role",
|
||||
})
|
||||
case "grantscopeid":
|
||||
f.StringVar(&base.StringVar{
|
||||
Name: "grant-scope-id",
|
||||
Target: &c.flagGrantScopeId,
|
||||
Usage: "The scope ID for grants set on the role",
|
||||
})
|
||||
case "principal":
|
||||
f.StringSliceVar(&base.StringSliceVar{
|
||||
Name: "principal",
|
||||
Target: &c.flagPrincipals,
|
||||
Usage: "The principals (users or groups) to add, remove, or set. May be specified multiple times.",
|
||||
})
|
||||
case "grant":
|
||||
f.StringSliceVar(&base.StringSliceVar{
|
||||
Name: "grant",
|
||||
Target: &c.flagGrants,
|
||||
Usage: "The grants to add, remove, or set. May be specified multiple times. Can be in compact string format or JSON (be sure to escape JSON properly).",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generateRoleTableOutput(role *roles.Role) string {
|
||||
var output []string
|
||||
if true {
|
||||
output = []string{
|
||||
"",
|
||||
"Role information:",
|
||||
fmt.Sprintf(" ID: %s", role.Id),
|
||||
fmt.Sprintf(" Created At: %s", role.CreatedTime.Local().Format(time.RFC3339)),
|
||||
fmt.Sprintf(" Updated At: %s", role.UpdatedTime.Local().Format(time.RFC3339)),
|
||||
fmt.Sprintf(" Version: %d", role.Version),
|
||||
}
|
||||
}
|
||||
if role.Name != nil {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Name: %s", *role.Name),
|
||||
)
|
||||
}
|
||||
if role.Description != nil {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Description: %s", *role.Description),
|
||||
)
|
||||
}
|
||||
if role.GrantScopeId != nil {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Grant Scope ID: %s", *role.GrantScopeId),
|
||||
)
|
||||
}
|
||||
if len(role.Principals) > 0 {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Principals: %s", ""),
|
||||
)
|
||||
}
|
||||
for _, principal := range role.Principals {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" ID: %s", principal.Id),
|
||||
fmt.Sprintf(" Type: %s", principal.Type),
|
||||
fmt.Sprintf(" Scope ID: %s", principal.ScopeId),
|
||||
)
|
||||
}
|
||||
if len(role.GrantsCanonical) > 0 {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Canonical Grants: %s", ""),
|
||||
)
|
||||
}
|
||||
for _, grant := range role.GrantsCanonical {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" %s", grant),
|
||||
)
|
||||
|
||||
}
|
||||
return base.WrapForHelpText(output)
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/helper/strutil"
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/api/roles"
|
||||
"github.com/hashicorp/watchtower/api/scopes"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/hashicorp/watchtower/internal/perms"
|
||||
"github.com/kr/pretty"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
var _ cli.Command = (*Command)(nil)
|
||||
var _ cli.CommandAutocomplete = (*Command)(nil)
|
||||
|
||||
type Command struct {
|
||||
*base.Command
|
||||
|
||||
Func string
|
||||
|
||||
flagId string
|
||||
flagName string
|
||||
flagDescription string
|
||||
flagGrantScopeId string
|
||||
flagPrincipals []string
|
||||
flagGrants []string
|
||||
}
|
||||
|
||||
func (c *Command) Synopsis() string {
|
||||
switch c.Func {
|
||||
case "create", "update", "read", "delete", "list":
|
||||
return synopsisFunc(c.Func)
|
||||
case "add-principals", "set-principals", "remove-principals":
|
||||
return principalsGrantsSynopsisFunc(c.Func, true)
|
||||
case "add-grants", "set-grants", "remove-grants":
|
||||
return principalsGrantsSynopsisFunc(c.Func, false)
|
||||
}
|
||||
return "Manage Watchtower roles"
|
||||
}
|
||||
|
||||
var helpMap = map[string]func() string{
|
||||
"create": createHelp,
|
||||
"update": updateHelp,
|
||||
"read": readHelp,
|
||||
"delete": deleteHelp,
|
||||
"list": listHelp,
|
||||
"add-principals": addPrincipalsHelp,
|
||||
"set-principals": setPrincipalsHelp,
|
||||
"remove-principals": removePrincipalsHelp,
|
||||
"add-grants": addPrincipalsHelp,
|
||||
"set-grants": setPrincipalsHelp,
|
||||
"remove-grants": removePrincipalsHelp,
|
||||
}
|
||||
|
||||
var flagsMap = map[string][]string{
|
||||
"create": {"name", "description", "grantscopeid"},
|
||||
"update": {"id", "name", "description", "grantscopeid"},
|
||||
"read": {"id"},
|
||||
"delete": {"id"},
|
||||
"add-principals": {"id", "principal"},
|
||||
"set-principals": {"id", "principal"},
|
||||
"remove-principals": {"id", "principal"},
|
||||
"add-grants": {"id", "grant"},
|
||||
"set-grants": {"id", "grant"},
|
||||
"remove-grants": {"id", "grant"},
|
||||
}
|
||||
|
||||
func (c *Command) Help() string {
|
||||
if c.Func == "" {
|
||||
return baseHelp()
|
||||
}
|
||||
return helpMap[c.Func]() + "\n\n" + c.Flags().Help()
|
||||
}
|
||||
|
||||
func (c *Command) Flags() *base.FlagSets {
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetClient | base.FlagSetOutputFormat)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
|
||||
populateFlags(c, f, flagsMap[c.Func])
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *Command) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *Command) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *Command) Run(args []string) int {
|
||||
if c.Func == "" {
|
||||
return cli.RunResultHelp
|
||||
}
|
||||
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
if strutil.StrListContains(flagsMap[c.Func], "id") && c.flagId == "" {
|
||||
c.UI.Error("ID is required but not passed in via -id")
|
||||
return 1
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error creating API client: %s", err.Error()))
|
||||
return 2
|
||||
}
|
||||
|
||||
role := &roles.Role{
|
||||
Client: client,
|
||||
Id: c.flagId,
|
||||
}
|
||||
switch c.flagName {
|
||||
case "":
|
||||
case "null":
|
||||
role.SetDefault("name")
|
||||
default:
|
||||
role.Name = api.String(c.flagName)
|
||||
}
|
||||
switch c.flagDescription {
|
||||
case "":
|
||||
case "null":
|
||||
role.SetDefault("description")
|
||||
default:
|
||||
role.Description = api.String(c.flagDescription)
|
||||
}
|
||||
switch c.flagGrantScopeId {
|
||||
case "":
|
||||
case "null":
|
||||
role.SetDefault("grantscopeid")
|
||||
default:
|
||||
role.GrantScopeId = api.String(c.flagGrantScopeId)
|
||||
}
|
||||
|
||||
principals := c.flagPrincipals
|
||||
grants := c.flagGrants
|
||||
switch c.Func {
|
||||
case "add-principals", "remove-principals":
|
||||
if len(c.flagPrincipals) == 0 {
|
||||
c.UI.Error("No principals supplied via -principal")
|
||||
return 1
|
||||
}
|
||||
|
||||
case "add-grants", "remove-grants":
|
||||
if len(c.flagGrants) == 0 {
|
||||
c.UI.Error("No grants supplied via -grant")
|
||||
return 1
|
||||
}
|
||||
|
||||
case "set-principals":
|
||||
switch len(c.flagPrincipals) {
|
||||
case 0:
|
||||
case 1:
|
||||
if c.flagPrincipals[0] == "null" {
|
||||
principals = []string{}
|
||||
}
|
||||
}
|
||||
if principals == nil {
|
||||
c.UI.Error("No principals supplied via -principals")
|
||||
return 1
|
||||
}
|
||||
|
||||
case "set-grants":
|
||||
switch len(c.flagGrants) {
|
||||
case 0:
|
||||
case 1:
|
||||
if c.flagGrants[0] == "null" {
|
||||
grants = []string{}
|
||||
}
|
||||
}
|
||||
if grants == nil {
|
||||
c.UI.Error("No grants supplied via -grant")
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
if len(grants) > 0 {
|
||||
for _, grant := range grants {
|
||||
_, err := perms.Parse("global", "", grant)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Errorf("Grant %q could not be parsed successfully: %w", grant, err).Error())
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var apiErr *api.Error
|
||||
|
||||
type crudl interface {
|
||||
CreateRole(context.Context, *roles.Role) (*roles.Role, *api.Error, error)
|
||||
UpdateRole(context.Context, *roles.Role) (*roles.Role, *api.Error, error)
|
||||
ReadRole(context.Context, *roles.Role) (*roles.Role, *api.Error, error)
|
||||
DeleteRole(context.Context, *roles.Role) (bool, *api.Error, error)
|
||||
ListRoles(context.Context) ([]*roles.Role, *api.Error, error)
|
||||
}
|
||||
var actor crudl
|
||||
var existed bool
|
||||
var listedRoles []*roles.Role
|
||||
|
||||
switch {
|
||||
case client.Project() != "":
|
||||
project := &scopes.Project{
|
||||
Client: client,
|
||||
}
|
||||
actor = project
|
||||
|
||||
case client.Org() != "":
|
||||
org := &scopes.Org{
|
||||
Client: client,
|
||||
}
|
||||
actor = org
|
||||
|
||||
default:
|
||||
// TODO: Handle global case
|
||||
c.UI.Error("TODO")
|
||||
}
|
||||
|
||||
if actor == nil {
|
||||
c.UI.Error("Unable to determine the right scope for the command")
|
||||
return 1
|
||||
}
|
||||
|
||||
// Perform check-and-set when needed
|
||||
switch c.Func {
|
||||
case "create", "read", "delete", "list":
|
||||
// These don't udpate so don't need the existing version
|
||||
default:
|
||||
existingRole, existingApiErr, existingErr := actor.ReadRole(c.Context, role)
|
||||
if existingErr != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error performing initial check-and-set read: %s", err.Error()))
|
||||
return 2
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error from controller when performing initial check-and-set read: %s", pretty.Sprint(apiErr)))
|
||||
return 1
|
||||
}
|
||||
role.Version = existingRole.Version
|
||||
}
|
||||
|
||||
switch c.Func {
|
||||
case "create":
|
||||
role, apiErr, err = actor.CreateRole(c.Context, role)
|
||||
case "update":
|
||||
role, apiErr, err = actor.UpdateRole(c.Context, role)
|
||||
case "read":
|
||||
role, apiErr, err = actor.ReadRole(c.Context, role)
|
||||
case "delete":
|
||||
existed, apiErr, err = actor.DeleteRole(c.Context, role)
|
||||
case "list":
|
||||
listedRoles, apiErr, err = actor.ListRoles(c.Context)
|
||||
case "add-principals":
|
||||
role, apiErr, err = role.AddPrincipals(c.Context, principals)
|
||||
case "set-principals":
|
||||
role, apiErr, err = role.SetPrincipals(c.Context, principals)
|
||||
case "remove-principals":
|
||||
role, apiErr, err = role.RemovePrincipals(c.Context, principals)
|
||||
case "add-grants":
|
||||
role, apiErr, err = role.AddGrants(c.Context, grants)
|
||||
case "set-grants":
|
||||
role, apiErr, err = role.SetGrants(c.Context, grants)
|
||||
case "remove-grants":
|
||||
role, apiErr, err = role.RemoveGrants(c.Context, grants)
|
||||
}
|
||||
|
||||
plural := "role"
|
||||
if c.Func == "list" {
|
||||
plural = "roles"
|
||||
}
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error()))
|
||||
return 2
|
||||
}
|
||||
if apiErr != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, pretty.Sprint(apiErr)))
|
||||
return 1
|
||||
}
|
||||
|
||||
switch c.Func {
|
||||
case "delete":
|
||||
switch base.Format(c.UI) {
|
||||
case "json":
|
||||
c.UI.Output("null")
|
||||
case "table":
|
||||
output := "The delete operation completed successfully"
|
||||
switch existed {
|
||||
case true:
|
||||
output += "."
|
||||
default:
|
||||
output += ", however the resource did not exist at the time."
|
||||
}
|
||||
c.UI.Output(output)
|
||||
}
|
||||
return 0
|
||||
|
||||
case "list":
|
||||
if len(listedRoles) == 0 {
|
||||
c.UI.Output("No roles found")
|
||||
return 0
|
||||
}
|
||||
switch base.Format(c.UI) {
|
||||
case "json":
|
||||
b, err := base.JsonFormatter{}.Format(listedRoles)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error formatting to JSON: %w", err).Error())
|
||||
return 1
|
||||
}
|
||||
c.UI.Output(string(b))
|
||||
case "table":
|
||||
var output []string
|
||||
output = []string{
|
||||
"",
|
||||
"Role information:",
|
||||
}
|
||||
for i, r := range listedRoles {
|
||||
if i > 0 {
|
||||
output = append(output, "")
|
||||
}
|
||||
if true {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" ID: %s", r.Id),
|
||||
)
|
||||
}
|
||||
if r.Name != nil {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Name: %s", *r.Name),
|
||||
)
|
||||
}
|
||||
if r.Description != nil {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Description: %s", *r.Description),
|
||||
)
|
||||
}
|
||||
}
|
||||
c.UI.Output(base.WrapForHelpText(output))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
switch base.Format(c.UI) {
|
||||
case "table":
|
||||
c.UI.Output(generateRoleTableOutput(role))
|
||||
case "json":
|
||||
b, err := base.JsonFormatter{}.Format(role)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Errorf("Error formatting to JSON: %w", err).Error())
|
||||
return 1
|
||||
}
|
||||
c.UI.Output(string(b))
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package scopes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/watchtower/api/scopes"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
)
|
||||
|
||||
func printProject(in *scopes.Project) string {
|
||||
var ret []string
|
||||
// This if true is here to line up columns for easy editing
|
||||
if true {
|
||||
ret = append(ret, []string{
|
||||
"",
|
||||
"Project information:",
|
||||
fmt.Sprintf(" ID: %s", in.Id),
|
||||
fmt.Sprintf(" Created Time: %s", in.CreatedTime.Local().Format(time.RFC3339)),
|
||||
fmt.Sprintf(" Updated Time: %s", in.UpdatedTime.Local().Format(time.RFC3339)),
|
||||
}...,
|
||||
)
|
||||
}
|
||||
if in.Name != nil {
|
||||
ret = append(ret,
|
||||
fmt.Sprintf(" Name: %s", *in.Name),
|
||||
)
|
||||
}
|
||||
if in.Description != nil {
|
||||
ret = append(ret,
|
||||
fmt.Sprintf(" Description: %s", *in.Description),
|
||||
)
|
||||
}
|
||||
|
||||
return base.WrapForHelpText(ret)
|
||||
}
|
||||
@@ -43,7 +43,7 @@ Usage: watchtower projects create
|
||||
}
|
||||
|
||||
func (c *CreateProjectCommand) Flags() *base.FlagSets {
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetOutputFormat)
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetClient | base.FlagSetOutputFormat)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
|
||||
@@ -105,8 +105,11 @@ func (c *CreateProjectCommand) Run(args []string) int {
|
||||
case apiErr != nil:
|
||||
c.UI.Error(pretty.Sprint(apiErr))
|
||||
return 2
|
||||
default:
|
||||
c.UI.Info(pretty.Sprint(project))
|
||||
}
|
||||
|
||||
switch base.Format(c.UI) {
|
||||
case "table":
|
||||
c.UI.Output(printProject(project))
|
||||
}
|
||||
|
||||
return 0
|
||||
|
||||
@@ -43,7 +43,7 @@ Usage: watchtower projects read
|
||||
}
|
||||
|
||||
func (c *ReadProjectCommand) Flags() *base.FlagSets {
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetOutputFormat)
|
||||
set := c.FlagSet(base.FlagSetHTTP | base.FlagSetClient | base.FlagSetOutputFormat)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
|
||||
@@ -97,8 +97,11 @@ func (c *ReadProjectCommand) Run(args []string) int {
|
||||
case apiErr != nil:
|
||||
c.UI.Error(pretty.Sprint(apiErr))
|
||||
return 2
|
||||
default:
|
||||
c.UI.Info(pretty.Sprint(project))
|
||||
}
|
||||
|
||||
switch base.Format(c.UI) {
|
||||
case "table":
|
||||
c.UI.Output(printProject(project))
|
||||
}
|
||||
|
||||
return 0
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
type Formatter interface {
|
||||
//Output(ui cli.Ui, secret *api.Secret, data interface{}) error
|
||||
Format(data interface{}) ([]byte, error)
|
||||
}
|
||||
|
||||
var Formatters = map[string]Formatter{
|
||||
"json": base.JsonFormatter{},
|
||||
"table": base.TableFormatter{},
|
||||
"yaml": base.YamlFormatter{},
|
||||
"yml": base.YamlFormatter{},
|
||||
}
|
||||
|
||||
func Format(ui cli.Ui) string {
|
||||
switch ui.(type) {
|
||||
case *WatchtowerUI:
|
||||
return ui.(*WatchtowerUI).format
|
||||
}
|
||||
|
||||
format := os.Getenv(base.EnvWatchtowerCLIFormat)
|
||||
if format == "" {
|
||||
format = "table"
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
+5
-10
@@ -18,11 +18,6 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
type WatchtowerUI struct {
|
||||
cli.Ui
|
||||
format string
|
||||
}
|
||||
|
||||
// setupEnv parses args and may replace them and sets some env vars to known
|
||||
// values based on format options
|
||||
func setupEnv(args []string) (retArgs []string, format string, outputCurlString bool) {
|
||||
@@ -128,7 +123,7 @@ func RunCustom(args []string, runOpts *RunOptions) int {
|
||||
uiErrWriter = ioutil.Discard
|
||||
}
|
||||
|
||||
ui := &WatchtowerUI{
|
||||
ui := &base.WatchtowerUI{
|
||||
Ui: &cli.ColoredUi{
|
||||
ErrorColor: cli.UiColorRed,
|
||||
WarnColor: cli.UiColorYellow,
|
||||
@@ -138,10 +133,10 @@ func RunCustom(args []string, runOpts *RunOptions) int {
|
||||
ErrorWriter: uiErrWriter,
|
||||
},
|
||||
},
|
||||
format: format,
|
||||
Format: format,
|
||||
}
|
||||
|
||||
serverCmdUi := &WatchtowerUI{
|
||||
serverCmdUi := &base.WatchtowerUI{
|
||||
Ui: &cli.ColoredUi{
|
||||
ErrorColor: cli.UiColorRed,
|
||||
WarnColor: cli.UiColorYellow,
|
||||
@@ -150,10 +145,10 @@ func RunCustom(args []string, runOpts *RunOptions) int {
|
||||
Writer: runOpts.Stdout,
|
||||
},
|
||||
},
|
||||
format: format,
|
||||
Format: format,
|
||||
}
|
||||
|
||||
if _, ok := Formatters[format]; !ok {
|
||||
if _, ok := base.Formatters[format]; !ok {
|
||||
ui.Error(fmt.Sprintf("Invalid output format: %s", format))
|
||||
return 1
|
||||
}
|
||||
|
||||
+67
-11
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDomain_PublicPrivateId(t *testing.T) {
|
||||
func TestDomain_Ids(t *testing.T) {
|
||||
const (
|
||||
createTableBase = `
|
||||
create table if not exists test_table_{{rep}}_id (
|
||||
@@ -29,7 +29,7 @@ returning id;
|
||||
conn, _ := TestSetup(t, "postgres")
|
||||
db := conn.DB()
|
||||
|
||||
for _, typ := range []string{"public", "private"} {
|
||||
for _, typ := range []string{"public", "private", "role", "scope"} {
|
||||
createTable := strings.Replace(createTableBase, "{{rep}}", typ, -1)
|
||||
insert := strings.Replace(insertBase, "{{rep}}", typ, -1)
|
||||
|
||||
@@ -37,17 +37,44 @@ returning id;
|
||||
t.Fatalf("query: \n%s\n error: %s", createTable, err)
|
||||
}
|
||||
|
||||
failTests := []string{
|
||||
" ",
|
||||
"bar",
|
||||
"00000009",
|
||||
failTests := []struct {
|
||||
value string
|
||||
exception string
|
||||
}{
|
||||
{
|
||||
" ",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"00000009",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"r_default",
|
||||
"role",
|
||||
},
|
||||
{
|
||||
"global",
|
||||
"scope",
|
||||
},
|
||||
}
|
||||
for _, tt := range failTests {
|
||||
value := tt
|
||||
t.Run(tt, func(t *testing.T) {
|
||||
t.Logf("insert value: %q", value)
|
||||
if _, err := db.Query(insert, value); err == nil {
|
||||
t.Errorf("want error, got no error for inserting public_id: %s", value)
|
||||
t.Run(tt.value, func(t *testing.T) {
|
||||
t.Logf("insert value: %q", tt.value)
|
||||
_, err := db.Query(insert, tt.value)
|
||||
switch {
|
||||
case err == nil && tt.exception != typ:
|
||||
t.Errorf("want error, got no error for inserting public_id: %s", tt.value)
|
||||
case err == nil && tt.exception == typ:
|
||||
// All good
|
||||
case err != nil && tt.exception != typ:
|
||||
// All good
|
||||
default:
|
||||
t.Fatal("unhandled")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -345,3 +372,32 @@ returning public_id;
|
||||
require.NoError(err)
|
||||
assert.Equal(3, v)
|
||||
}
|
||||
|
||||
func TestDomain_DisallowDefaultRoleModification(t *testing.T) {
|
||||
conn, _ := TestSetup(t, "postgres")
|
||||
db := conn.DB()
|
||||
|
||||
_, err := db.Exec(`delete from iam_role where public_id = $1`, "r_default")
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, `pq: deletion of default role not allowed`, err.Error())
|
||||
|
||||
// This actually tests not just default, but all roles
|
||||
_, err = db.Exec(`update iam_role set public_id = $1 where public_id = $2`, "r_something", "r_default")
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, `pq: update of role primary key not allowed`, err.Error())
|
||||
}
|
||||
|
||||
func TestDomain_DefaultUsersExist(t *testing.T) {
|
||||
conn, _ := TestSetup(t, "postgres")
|
||||
db := conn.DB()
|
||||
|
||||
for _, val := range []string{"u_anon", "u_auth"} {
|
||||
rows, err := db.Query(`select from iam_user where public_id = $1`, val)
|
||||
require.NoError(t, err)
|
||||
var count int
|
||||
for rows.Next() {
|
||||
count++
|
||||
}
|
||||
assert.Equal(t, 1, count)
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,13 @@ check(
|
||||
comment on domain wt_scope_id is
|
||||
'"u_anon", "u_auth", or random ID generated with github.com/hashicorp/vault/sdk/helper/base62';
|
||||
|
||||
create domain wt_role_id as text
|
||||
check(
|
||||
length(trim(value)) > 10 or value = 'r_default'
|
||||
);
|
||||
comment on domain wt_scope_id is
|
||||
'"r_default", or random ID generated with github.com/hashicorp/vault/sdk/helper/base62';
|
||||
|
||||
create domain wt_timestamp as
|
||||
timestamp with time zone
|
||||
default current_timestamp;
|
||||
@@ -453,7 +460,7 @@ drop table iam_role_grant cascade;
|
||||
drop function iam_sub_names cascade;
|
||||
drop function iam_immutable_scope_type_func cascade;
|
||||
drop function iam_sub_scopes_func cascade;
|
||||
drop function iam_immutable_role cascade;
|
||||
drop function iam_immutable_role_principal cascade;
|
||||
drop function iam_user_role_scope_check cascade;
|
||||
drop function iam_group_role_scope_check cascade;
|
||||
drop function iam_group_member_scope_check cascade;
|
||||
@@ -814,7 +821,7 @@ insert into iam_user (public_id, name, description, scope_id)
|
||||
values ('u_auth', 'authenticated', 'The authenticated user matches any user that has a valid token', 'global');
|
||||
|
||||
create table iam_role (
|
||||
public_id wt_public_id primary key,
|
||||
public_id wt_role_id primary key,
|
||||
create_time wt_timestamp,
|
||||
update_time wt_timestamp,
|
||||
name text,
|
||||
@@ -837,7 +844,7 @@ create table iam_role (
|
||||
-- Grants are immutable, which is enforced via the trigger below
|
||||
create table iam_role_grant (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_public_id -- pk
|
||||
role_id wt_role_id -- pk
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
@@ -907,6 +914,51 @@ before
|
||||
insert or update on iam_role
|
||||
for each row execute procedure grant_scope_id_valid();
|
||||
|
||||
-- disallow_default_role_deletion prevents the default role (r_default) from
|
||||
-- being deleted
|
||||
create or replace function
|
||||
disallow_default_role_deletion()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
if old.public_id = 'r_default' then
|
||||
raise exception 'deletion of default role not allowed';
|
||||
end if;
|
||||
return old;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger
|
||||
disallow_default_role_deletion
|
||||
before
|
||||
delete on iam_role
|
||||
for each row execute procedure disallow_default_role_deletion();
|
||||
|
||||
-- immutable_default_role_id prevents the a role's id from being updated.
|
||||
create or replace function
|
||||
immutable_role_id()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
if new.public_id is distinct from old.public_id then
|
||||
raise exception 'update of role primary key not allowed';
|
||||
end if;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger
|
||||
immutable_role_id
|
||||
before
|
||||
update on iam_role
|
||||
for each row execute procedure immutable_role_id();
|
||||
|
||||
insert into iam_role (public_id, name, description, scope_id)
|
||||
values('r_default', 'default', 'default role', 'global');
|
||||
|
||||
insert into iam_role_grant (role_id, canonical_grant, raw_grant)
|
||||
values('r_default', 'type=org;actions=list', 'type=org;actions=list');
|
||||
|
||||
create table iam_group (
|
||||
public_id wt_public_id not null primary key,
|
||||
create_time wt_timestamp,
|
||||
@@ -953,10 +1005,11 @@ update on iam_group
|
||||
|
||||
-- iam_user_role contains roles that have been assigned to users. Users can be
|
||||
-- from any scope. The rows in this table must be immutable after insert, which
|
||||
-- will be ensured with a before update trigger using iam_immutable_role().
|
||||
-- will be ensured with a before update trigger using
|
||||
-- iam_immutable_role_principal().
|
||||
create table iam_user_role (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_public_id
|
||||
role_id wt_role_id
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
@@ -970,10 +1023,10 @@ create table iam_user_role (
|
||||
-- iam_group_role contains roles that have been assigned to groups.
|
||||
-- Groups can be from any scope. The rows in this table must be immutable after
|
||||
-- insert, which will be ensured with a before update trigger using
|
||||
-- iam_immutable_role().
|
||||
-- iam_immutable_role_principal().
|
||||
create table iam_group_role (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_public_id
|
||||
role_id wt_role_id
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
@@ -997,6 +1050,12 @@ begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
insert into iam_user_role (role_id, principal_id)
|
||||
values
|
||||
('r_default', 'u_anon'),
|
||||
('r_default', 'u_auth');
|
||||
|
||||
|
||||
-- iam_principle_role provides a consolidated view all principal roles assigned
|
||||
-- (user and group roles).
|
||||
create view iam_principal_role as
|
||||
@@ -1032,9 +1091,9 @@ where
|
||||
gr.role_id = r.public_id and
|
||||
g.public_id = gr.principal_id;
|
||||
|
||||
-- iam_immutable_role() ensures that roles assigned to principals are immutable.
|
||||
-- iam_immutable_role_principal() ensures that roles assigned to principals are immutable.
|
||||
create or replace function
|
||||
iam_immutable_role()
|
||||
iam_immutable_role_principal()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
@@ -1042,10 +1101,10 @@ begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger immutable_role
|
||||
create trigger immutable_role_principal
|
||||
before
|
||||
update on iam_user_role
|
||||
for each row execute procedure iam_immutable_role();
|
||||
for each row execute procedure iam_immutable_role_principal();
|
||||
|
||||
create trigger
|
||||
immutable_create_time
|
||||
@@ -1059,10 +1118,10 @@ before
|
||||
insert on iam_user_role
|
||||
for each row execute procedure default_create_time();
|
||||
|
||||
create trigger immutable_role
|
||||
create trigger immutable_role_principal
|
||||
before
|
||||
update on iam_group_role
|
||||
for each row execute procedure iam_immutable_role();
|
||||
for each row execute procedure iam_immutable_role_principal();
|
||||
|
||||
create trigger
|
||||
immutable_create_time
|
||||
|
||||
@@ -28,6 +28,13 @@ check(
|
||||
comment on domain wt_scope_id is
|
||||
'"u_anon", "u_auth", or random ID generated with github.com/hashicorp/vault/sdk/helper/base62';
|
||||
|
||||
create domain wt_role_id as text
|
||||
check(
|
||||
length(trim(value)) > 10 or value = 'r_default'
|
||||
);
|
||||
comment on domain wt_scope_id is
|
||||
'"r_default", or random ID generated with github.com/hashicorp/vault/sdk/helper/base62';
|
||||
|
||||
create domain wt_timestamp as
|
||||
timestamp with time zone
|
||||
default current_timestamp;
|
||||
|
||||
@@ -18,7 +18,7 @@ drop table iam_role_grant cascade;
|
||||
drop function iam_sub_names cascade;
|
||||
drop function iam_immutable_scope_type_func cascade;
|
||||
drop function iam_sub_scopes_func cascade;
|
||||
drop function iam_immutable_role cascade;
|
||||
drop function iam_immutable_role_principal cascade;
|
||||
drop function iam_user_role_scope_check cascade;
|
||||
drop function iam_group_role_scope_check cascade;
|
||||
drop function iam_group_member_scope_check cascade;
|
||||
|
||||
@@ -339,7 +339,7 @@ insert into iam_user (public_id, name, description, scope_id)
|
||||
values ('u_auth', 'authenticated', 'The authenticated user matches any user that has a valid token', 'global');
|
||||
|
||||
create table iam_role (
|
||||
public_id wt_public_id primary key,
|
||||
public_id wt_role_id primary key,
|
||||
create_time wt_timestamp,
|
||||
update_time wt_timestamp,
|
||||
name text,
|
||||
@@ -362,7 +362,7 @@ create table iam_role (
|
||||
-- Grants are immutable, which is enforced via the trigger below
|
||||
create table iam_role_grant (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_public_id -- pk
|
||||
role_id wt_role_id -- pk
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
@@ -432,6 +432,51 @@ before
|
||||
insert or update on iam_role
|
||||
for each row execute procedure grant_scope_id_valid();
|
||||
|
||||
-- disallow_default_role_deletion prevents the default role (r_default) from
|
||||
-- being deleted
|
||||
create or replace function
|
||||
disallow_default_role_deletion()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
if old.public_id = 'r_default' then
|
||||
raise exception 'deletion of default role not allowed';
|
||||
end if;
|
||||
return old;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger
|
||||
disallow_default_role_deletion
|
||||
before
|
||||
delete on iam_role
|
||||
for each row execute procedure disallow_default_role_deletion();
|
||||
|
||||
-- immutable_default_role_id prevents the a role's id from being updated.
|
||||
create or replace function
|
||||
immutable_role_id()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
if new.public_id is distinct from old.public_id then
|
||||
raise exception 'update of role primary key not allowed';
|
||||
end if;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger
|
||||
immutable_role_id
|
||||
before
|
||||
update on iam_role
|
||||
for each row execute procedure immutable_role_id();
|
||||
|
||||
insert into iam_role (public_id, name, description, scope_id)
|
||||
values('r_default', 'default', 'default role', 'global');
|
||||
|
||||
insert into iam_role_grant (role_id, canonical_grant, raw_grant)
|
||||
values('r_default', 'type=org;actions=list', 'type=org;actions=list');
|
||||
|
||||
create table iam_group (
|
||||
public_id wt_public_id not null primary key,
|
||||
create_time wt_timestamp,
|
||||
@@ -478,10 +523,11 @@ update on iam_group
|
||||
|
||||
-- iam_user_role contains roles that have been assigned to users. Users can be
|
||||
-- from any scope. The rows in this table must be immutable after insert, which
|
||||
-- will be ensured with a before update trigger using iam_immutable_role().
|
||||
-- will be ensured with a before update trigger using
|
||||
-- iam_immutable_role_principal().
|
||||
create table iam_user_role (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_public_id
|
||||
role_id wt_role_id
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
@@ -495,10 +541,10 @@ create table iam_user_role (
|
||||
-- iam_group_role contains roles that have been assigned to groups.
|
||||
-- Groups can be from any scope. The rows in this table must be immutable after
|
||||
-- insert, which will be ensured with a before update trigger using
|
||||
-- iam_immutable_role().
|
||||
-- iam_immutable_role_principal().
|
||||
create table iam_group_role (
|
||||
create_time wt_timestamp,
|
||||
role_id wt_public_id
|
||||
role_id wt_role_id
|
||||
references iam_role(public_id)
|
||||
on delete cascade
|
||||
on update cascade,
|
||||
@@ -522,6 +568,12 @@ begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
insert into iam_user_role (role_id, principal_id)
|
||||
values
|
||||
('r_default', 'u_anon'),
|
||||
('r_default', 'u_auth');
|
||||
|
||||
|
||||
-- iam_principle_role provides a consolidated view all principal roles assigned
|
||||
-- (user and group roles).
|
||||
create view iam_principal_role as
|
||||
@@ -557,9 +609,9 @@ where
|
||||
gr.role_id = r.public_id and
|
||||
g.public_id = gr.principal_id;
|
||||
|
||||
-- iam_immutable_role() ensures that roles assigned to principals are immutable.
|
||||
-- iam_immutable_role_principal() ensures that roles assigned to principals are immutable.
|
||||
create or replace function
|
||||
iam_immutable_role()
|
||||
iam_immutable_role_principal()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
@@ -567,10 +619,10 @@ begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger immutable_role
|
||||
create trigger immutable_role_principal
|
||||
before
|
||||
update on iam_user_role
|
||||
for each row execute procedure iam_immutable_role();
|
||||
for each row execute procedure iam_immutable_role_principal();
|
||||
|
||||
create trigger
|
||||
immutable_create_time
|
||||
@@ -584,10 +636,10 @@ before
|
||||
insert on iam_user_role
|
||||
for each row execute procedure default_create_time();
|
||||
|
||||
create trigger immutable_role
|
||||
create trigger immutable_role_principal
|
||||
before
|
||||
update on iam_group_role
|
||||
for each row execute procedure iam_immutable_role();
|
||||
for each row execute procedure iam_immutable_role_principal();
|
||||
|
||||
create trigger
|
||||
immutable_create_time
|
||||
|
||||
@@ -72,6 +72,46 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/orgs/{org_id}/auth-methods/{auth_method_id}:authenticate": {
|
||||
"post": {
|
||||
"summary": "Authenticate a user to an Org and retrieve an authentication token.",
|
||||
"operationId": "AuthenticationService_Authenticate",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.resources.authtokens.v1.AuthToken"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "org_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "auth_method_id",
|
||||
"description": "The id to the authmethod in the system being used for authentication. The auth method must be in the org\nbeing logged in to.",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.services.v1.AuthenticateRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"controller.api.services.v1.AuthenticationService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/orgs/{org_id}/groups": {
|
||||
"get": {
|
||||
"summary": "Lists all Groups",
|
||||
@@ -3051,43 +3091,10 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/orgs/{org_id}:authenticate": {
|
||||
"post": {
|
||||
"summary": "Authenticate a user to an Org and retrieve an authentication token.",
|
||||
"operationId": "OrgService_Authenticate",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.resources.authtokens.v1.AuthToken"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "org_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.api.services.v1.AuthenticateRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"controller.api.services.v1.OrgService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/orgs/{org_id}:deauthenticate": {
|
||||
"post": {
|
||||
"summary": "Deauthenticate an authentication token from an Org.",
|
||||
"operationId": "OrgService_Deauthenticate",
|
||||
"operationId": "AuthenticationService_Deauthenticate",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
@@ -3105,7 +3112,7 @@
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"controller.api.services.v1.OrgService"
|
||||
"controller.api.services.v1.AuthenticationService"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -3339,6 +3346,26 @@
|
||||
},
|
||||
"title": "HostSet is a collection of Hosts created and managed by a HostCatalog"
|
||||
},
|
||||
"controller.api.resources.roles.v1.Principal": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the principal.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of the principal.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"scope_id": {
|
||||
"type": "string",
|
||||
"description": "The scope ID of the principal.\nOutput only.",
|
||||
"readOnly": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.resources.roles.v1.Role": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -3382,20 +3409,20 @@
|
||||
"description": "The version can be used in subsiquent write requests to ensure this resource\nhas not changed and to fail the write if it has.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"user_ids": {
|
||||
"principal_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The principals that are assigned this role.\nOutput only.",
|
||||
"description": "The IDs (only) of principals that are assigned to this role.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"group_ids": {
|
||||
"principals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"$ref": "#/definitions/controller.api.resources.roles.v1.Principal"
|
||||
},
|
||||
"description": "Output only.",
|
||||
"description": "The principals that are assigned to this role.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"grants": {
|
||||
@@ -3403,7 +3430,7 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The grants that this role provides for it's principals.\nOutput only.",
|
||||
"description": "The grants that this role provides for its principals.\nOutput only.",
|
||||
"readOnly": true
|
||||
},
|
||||
"grants_canonical": {
|
||||
@@ -3578,13 +3605,7 @@
|
||||
"format": "int64",
|
||||
"description": "The version ensures the role hasn't changed since it was last retrieved and if\nit has the request will fail."
|
||||
},
|
||||
"user_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"group_ids": {
|
||||
"principal_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
@@ -3617,8 +3638,9 @@
|
||||
"type": "string",
|
||||
"description": "This can be \"cookie\" or \"token\". If not provided, \"token\" will be used. For now only type \"token\" is returned."
|
||||
},
|
||||
"password_credential": {
|
||||
"$ref": "#/definitions/controller.api.services.v1.PasswordCredential"
|
||||
"credentials": {
|
||||
"type": "object",
|
||||
"description": "credentials are the different possible credential names depending on what type of auth method is used.\nFor password auth method: should include only \"name\" and \"password\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3925,17 +3947,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.PasswordCredential": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"login_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.api.services.v1.RemoveFromHostSetResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
@@ -3989,13 +4000,7 @@
|
||||
"format": "int64",
|
||||
"description": "The version ensures the role hasn't changed since it was last retrieved and if\nit has the request will fail."
|
||||
},
|
||||
"user_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"group_ids": {
|
||||
"principal_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
@@ -4061,13 +4066,7 @@
|
||||
"format": "int64",
|
||||
"description": "The version ensures the role hasn't changed since it was last retrieved and if\nit has the request will fail."
|
||||
},
|
||||
"user_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"group_ids": {
|
||||
"principal_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
|
||||
@@ -27,6 +27,113 @@ const (
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type Principal struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The ID of the principal.
|
||||
// Output only.
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
// The type of the principal.
|
||||
// Output only.
|
||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
// The scope ID of the principal.
|
||||
// Output only.
|
||||
ScopeId string `protobuf:"bytes,3,opt,name=scope_id,proto3" json:"scope_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Principal) Reset() {
|
||||
*x = Principal{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Principal) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Principal) ProtoMessage() {}
|
||||
|
||||
func (x *Principal) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Principal.ProtoReflect.Descriptor instead.
|
||||
func (*Principal) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_resources_roles_v1_role_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Principal) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Principal) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Principal) GetScopeId() string {
|
||||
if x != nil {
|
||||
return x.ScopeId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Grant struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *Grant) Reset() {
|
||||
*x = Grant{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Grant) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Grant) ProtoMessage() {}
|
||||
|
||||
func (x *Grant) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Grant.ProtoReflect.Descriptor instead.
|
||||
func (*Grant) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_resources_roles_v1_role_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
// Role contains all fields related to a Role resource
|
||||
type Role struct {
|
||||
state protoimpl.MessageState
|
||||
@@ -58,12 +165,13 @@ type Role struct {
|
||||
// has not changed and to fail the write if it has.
|
||||
// Output only.
|
||||
Version uint32 `protobuf:"varint,8,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// The principals that are assigned this role.
|
||||
// The IDs (only) of principals that are assigned to this role.
|
||||
// Output only.
|
||||
UserIds []string `protobuf:"bytes,9,rep,name=user_ids,json=userIds,proto3" json:"user_ids,omitempty"`
|
||||
PrincipalIds []string `protobuf:"bytes,9,rep,name=principal_ids,proto3" json:"principal_ids,omitempty"`
|
||||
// The principals that are assigned to this role.
|
||||
// Output only.
|
||||
GroupIds []string `protobuf:"bytes,10,rep,name=group_ids,json=groupIds,proto3" json:"group_ids,omitempty"`
|
||||
// The grants that this role provides for it's principals.
|
||||
Principals []*Principal `protobuf:"bytes,10,rep,name=principals,proto3" json:"principals,omitempty"`
|
||||
// The grants that this role provides for its principals.
|
||||
// Output only.
|
||||
Grants []string `protobuf:"bytes,11,rep,name=grants,proto3" json:"grants,omitempty"`
|
||||
// The canonical version of the grants in the grants field with the same index.
|
||||
@@ -77,7 +185,7 @@ type Role struct {
|
||||
func (x *Role) Reset() {
|
||||
*x = Role{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[0]
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -90,7 +198,7 @@ func (x *Role) String() string {
|
||||
func (*Role) ProtoMessage() {}
|
||||
|
||||
func (x *Role) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[0]
|
||||
mi := &file_controller_api_resources_roles_v1_role_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -103,7 +211,7 @@ func (x *Role) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Role.ProtoReflect.Descriptor instead.
|
||||
func (*Role) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_resources_roles_v1_role_proto_rawDescGZIP(), []int{0}
|
||||
return file_controller_api_resources_roles_v1_role_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Role) GetId() string {
|
||||
@@ -162,16 +270,16 @@ func (x *Role) GetVersion() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Role) GetUserIds() []string {
|
||||
func (x *Role) GetPrincipalIds() []string {
|
||||
if x != nil {
|
||||
return x.UserIds
|
||||
return x.PrincipalIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Role) GetGroupIds() []string {
|
||||
func (x *Role) GetPrincipals() []*Principal {
|
||||
if x != nil {
|
||||
return x.GroupIds
|
||||
return x.Principals
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -209,48 +317,57 @@ var file_controller_api_resources_roles_v1_role_proto_rawDesc = []byte{
|
||||
0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x22, 0xbc, 0x04, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a,
|
||||
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a,
|
||||
0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a,
|
||||
0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a,
|
||||
0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x64, 0x69, 0x73,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64,
|
||||
0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73,
|
||||
0x12, 0x1b, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0a, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f,
|
||||
0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c,
|
||||
0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18,
|
||||
0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x4a, 0x73, 0x6f,
|
||||
0x6e, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74,
|
||||
0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65,
|
||||
0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
|
||||
0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x22,
|
||||
0x07, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x22, 0xf8, 0x04, 0x0a, 0x04, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
|
||||
0x64, 0x12, 0x30, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x0e, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x52, 0x0e, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69,
|
||||
0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x70,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64,
|
||||
0x73, 0x12, 0x4c, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x18,
|
||||
0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x73, 0x5f, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63,
|
||||
0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x5f, 0x6a, 0x73, 0x6f,
|
||||
0x6e, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x4a,
|
||||
0x73, 0x6f, 0x6e, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63,
|
||||
0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
||||
0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x3b, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -265,25 +382,28 @@ func file_controller_api_resources_roles_v1_role_proto_rawDescGZIP() []byte {
|
||||
return file_controller_api_resources_roles_v1_role_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_controller_api_resources_roles_v1_role_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_controller_api_resources_roles_v1_role_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_controller_api_resources_roles_v1_role_proto_goTypes = []interface{}{
|
||||
(*Role)(nil), // 0: controller.api.resources.roles.v1.Role
|
||||
(*wrappers.StringValue)(nil), // 1: google.protobuf.StringValue
|
||||
(*timestamp.Timestamp)(nil), // 2: google.protobuf.Timestamp
|
||||
(*wrappers.BoolValue)(nil), // 3: google.protobuf.BoolValue
|
||||
(*Principal)(nil), // 0: controller.api.resources.roles.v1.Principal
|
||||
(*Grant)(nil), // 1: controller.api.resources.roles.v1.Grant
|
||||
(*Role)(nil), // 2: controller.api.resources.roles.v1.Role
|
||||
(*wrappers.StringValue)(nil), // 3: google.protobuf.StringValue
|
||||
(*timestamp.Timestamp)(nil), // 4: google.protobuf.Timestamp
|
||||
(*wrappers.BoolValue)(nil), // 5: google.protobuf.BoolValue
|
||||
}
|
||||
var file_controller_api_resources_roles_v1_role_proto_depIdxs = []int32{
|
||||
1, // 0: controller.api.resources.roles.v1.Role.name:type_name -> google.protobuf.StringValue
|
||||
1, // 1: controller.api.resources.roles.v1.Role.description:type_name -> google.protobuf.StringValue
|
||||
2, // 2: controller.api.resources.roles.v1.Role.created_time:type_name -> google.protobuf.Timestamp
|
||||
2, // 3: controller.api.resources.roles.v1.Role.updated_time:type_name -> google.protobuf.Timestamp
|
||||
3, // 4: controller.api.resources.roles.v1.Role.disabled:type_name -> google.protobuf.BoolValue
|
||||
1, // 5: controller.api.resources.roles.v1.Role.grant_scope_id:type_name -> google.protobuf.StringValue
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
3, // 0: controller.api.resources.roles.v1.Role.name:type_name -> google.protobuf.StringValue
|
||||
3, // 1: controller.api.resources.roles.v1.Role.description:type_name -> google.protobuf.StringValue
|
||||
4, // 2: controller.api.resources.roles.v1.Role.created_time:type_name -> google.protobuf.Timestamp
|
||||
4, // 3: controller.api.resources.roles.v1.Role.updated_time:type_name -> google.protobuf.Timestamp
|
||||
5, // 4: controller.api.resources.roles.v1.Role.disabled:type_name -> google.protobuf.BoolValue
|
||||
3, // 5: controller.api.resources.roles.v1.Role.grant_scope_id:type_name -> google.protobuf.StringValue
|
||||
0, // 6: controller.api.resources.roles.v1.Role.principals:type_name -> controller.api.resources.roles.v1.Principal
|
||||
7, // [7:7] is the sub-list for method output_type
|
||||
7, // [7:7] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_controller_api_resources_roles_v1_role_proto_init() }
|
||||
@@ -293,6 +413,30 @@ func file_controller_api_resources_roles_v1_role_proto_init() {
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_controller_api_resources_roles_v1_role_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Principal); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_resources_roles_v1_role_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Grant); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_resources_roles_v1_role_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Role); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -311,7 +455,7 @@ func file_controller_api_resources_roles_v1_role_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_controller_api_resources_roles_v1_role_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,626 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.24.0
|
||||
// protoc v3.12.3
|
||||
// source: controller/api/services/v1/authenticate_service.proto
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
context "context"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
_struct "github.com/golang/protobuf/ptypes/struct"
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
|
||||
authtokens "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/authtokens"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// The layout of the struct for "credentials" field in AuthenticateRequest. This message isn't
|
||||
// directly referenced anywhere but is used here to define the expected field names and types.
|
||||
type PasswordCredentials struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PasswordCredentials) Reset() {
|
||||
*x = PasswordCredentials{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PasswordCredentials) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PasswordCredentials) ProtoMessage() {}
|
||||
|
||||
func (x *PasswordCredentials) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PasswordCredentials.ProtoReflect.Descriptor instead.
|
||||
func (*PasswordCredentials) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_authenticate_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PasswordCredentials) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PasswordCredentials) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthenticateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
|
||||
// The id to the authmethod in the system being used for authentication. The auth method must be in the org
|
||||
// being logged in to.
|
||||
AuthMethodId string `protobuf:"bytes,2,opt,name=auth_method_id,json=authMethodId,proto3" json:"auth_method_id,omitempty"`
|
||||
// This can be "cookie" or "token". If not provided, "token" will be used. For now only type "token" is returned.
|
||||
TokenType string `protobuf:"bytes,3,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"`
|
||||
// credentials are the different possible credential names depending on what type of auth method is used.
|
||||
// For password auth method: should include only "name" and "password".
|
||||
Credentials *_struct.Struct `protobuf:"bytes,8,opt,name=credentials,proto3" json:"credentials,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) Reset() {
|
||||
*x = AuthenticateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthenticateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AuthenticateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthenticateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AuthenticateRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_authenticate_service_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetOrgId() string {
|
||||
if x != nil {
|
||||
return x.OrgId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetAuthMethodId() string {
|
||||
if x != nil {
|
||||
return x.AuthMethodId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetTokenType() string {
|
||||
if x != nil {
|
||||
return x.TokenType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetCredentials() *_struct.Struct {
|
||||
if x != nil {
|
||||
return x.Credentials
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticateResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Item *authtokens.AuthToken `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) Reset() {
|
||||
*x = AuthenticateResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthenticateResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AuthenticateResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthenticateResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AuthenticateResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_authenticate_service_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) GetItem() *authtokens.AuthToken {
|
||||
if x != nil {
|
||||
return x.Item
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeauthenticateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DeauthenticateRequest) Reset() {
|
||||
*x = DeauthenticateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeauthenticateRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeauthenticateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeauthenticateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeauthenticateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeauthenticateRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_authenticate_service_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *DeauthenticateRequest) GetOrgId() string {
|
||||
if x != nil {
|
||||
return x.OrgId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeauthenticateResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *DeauthenticateResponse) Reset() {
|
||||
*x = DeauthenticateResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeauthenticateResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeauthenticateResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeauthenticateResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_authenticate_service_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeauthenticateResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeauthenticateResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_authenticate_service_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
var File_controller_api_services_v1_authenticate_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_api_services_v1_authenticate_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x35, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x1a, 0x2c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d,
|
||||
0x73, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f,
|
||||
0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e,
|
||||
0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
||||
0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x36, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x74, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x45, 0x0a, 0x13, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||
0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xac, 0x01, 0x0a,
|
||||
0x13, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x61,
|
||||
0x75, 0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x49,
|
||||
0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x39, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b,
|
||||
0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x5d, 0x0a, 0x14, 0x41,
|
||||
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x61, 0x75, 0x74,
|
||||
0x68, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x54,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x2e, 0x0a, 0x15, 0x44, 0x65,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x32, 0xff, 0x03, 0x0a, 0x15, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x89,
|
||||
0x02, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12,
|
||||
0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x95, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x47, 0x22, 0x3c, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61,
|
||||
0x75, 0x74, 0x68, 0x2d, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x61, 0x75, 0x74,
|
||||
0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74,
|
||||
0x65, 0x6d, 0x92, 0x41, 0x45, 0x12, 0x43, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e,
|
||||
0x20, 0x4f, 0x72, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76,
|
||||
0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x12, 0xd9, 0x01, 0x0a, 0x0e, 0x44,
|
||||
0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x31, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x60, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x22, 0x20, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x3a,
|
||||
0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x92, 0x41,
|
||||
0x35, 0x12, 0x33, 0x44, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61,
|
||||
0x6e, 0x20, 0x4f, 0x72, 0x67, 0x2e, 0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77,
|
||||
0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_controller_api_services_v1_authenticate_service_proto_rawDescOnce sync.Once
|
||||
file_controller_api_services_v1_authenticate_service_proto_rawDescData = file_controller_api_services_v1_authenticate_service_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_controller_api_services_v1_authenticate_service_proto_rawDescGZIP() []byte {
|
||||
file_controller_api_services_v1_authenticate_service_proto_rawDescOnce.Do(func() {
|
||||
file_controller_api_services_v1_authenticate_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_api_services_v1_authenticate_service_proto_rawDescData)
|
||||
})
|
||||
return file_controller_api_services_v1_authenticate_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_controller_api_services_v1_authenticate_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_controller_api_services_v1_authenticate_service_proto_goTypes = []interface{}{
|
||||
(*PasswordCredentials)(nil), // 0: controller.api.services.v1.PasswordCredentials
|
||||
(*AuthenticateRequest)(nil), // 1: controller.api.services.v1.AuthenticateRequest
|
||||
(*AuthenticateResponse)(nil), // 2: controller.api.services.v1.AuthenticateResponse
|
||||
(*DeauthenticateRequest)(nil), // 3: controller.api.services.v1.DeauthenticateRequest
|
||||
(*DeauthenticateResponse)(nil), // 4: controller.api.services.v1.DeauthenticateResponse
|
||||
(*_struct.Struct)(nil), // 5: google.protobuf.Struct
|
||||
(*authtokens.AuthToken)(nil), // 6: controller.api.resources.authtokens.v1.AuthToken
|
||||
}
|
||||
var file_controller_api_services_v1_authenticate_service_proto_depIdxs = []int32{
|
||||
5, // 0: controller.api.services.v1.AuthenticateRequest.credentials:type_name -> google.protobuf.Struct
|
||||
6, // 1: controller.api.services.v1.AuthenticateResponse.item:type_name -> controller.api.resources.authtokens.v1.AuthToken
|
||||
1, // 2: controller.api.services.v1.AuthenticationService.Authenticate:input_type -> controller.api.services.v1.AuthenticateRequest
|
||||
3, // 3: controller.api.services.v1.AuthenticationService.Deauthenticate:input_type -> controller.api.services.v1.DeauthenticateRequest
|
||||
2, // 4: controller.api.services.v1.AuthenticationService.Authenticate:output_type -> controller.api.services.v1.AuthenticateResponse
|
||||
4, // 5: controller.api.services.v1.AuthenticationService.Deauthenticate:output_type -> controller.api.services.v1.DeauthenticateResponse
|
||||
4, // [4:6] is the sub-list for method output_type
|
||||
2, // [2:4] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_controller_api_services_v1_authenticate_service_proto_init() }
|
||||
func file_controller_api_services_v1_authenticate_service_proto_init() {
|
||||
if File_controller_api_services_v1_authenticate_service_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_controller_api_services_v1_authenticate_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PasswordCredentials); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_authenticate_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthenticateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_authenticate_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthenticateResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_authenticate_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeauthenticateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_authenticate_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeauthenticateResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_controller_api_services_v1_authenticate_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_controller_api_services_v1_authenticate_service_proto_goTypes,
|
||||
DependencyIndexes: file_controller_api_services_v1_authenticate_service_proto_depIdxs,
|
||||
MessageInfos: file_controller_api_services_v1_authenticate_service_proto_msgTypes,
|
||||
}.Build()
|
||||
File_controller_api_services_v1_authenticate_service_proto = out.File
|
||||
file_controller_api_services_v1_authenticate_service_proto_rawDesc = nil
|
||||
file_controller_api_services_v1_authenticate_service_proto_goTypes = nil
|
||||
file_controller_api_services_v1_authenticate_service_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// AuthenticationServiceClient is the client API for AuthenticationService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type AuthenticationServiceClient interface {
|
||||
// Authenticate validates credentials provided and returns an auth token.
|
||||
Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error)
|
||||
// Logout terminates a user's current session.
|
||||
Deauthenticate(ctx context.Context, in *DeauthenticateRequest, opts ...grpc.CallOption) (*DeauthenticateResponse, error)
|
||||
}
|
||||
|
||||
type authenticationServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAuthenticationServiceClient(cc grpc.ClientConnInterface) AuthenticationServiceClient {
|
||||
return &authenticationServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *authenticationServiceClient) Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error) {
|
||||
out := new(AuthenticateResponse)
|
||||
err := c.cc.Invoke(ctx, "/controller.api.services.v1.AuthenticationService/Authenticate", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authenticationServiceClient) Deauthenticate(ctx context.Context, in *DeauthenticateRequest, opts ...grpc.CallOption) (*DeauthenticateResponse, error) {
|
||||
out := new(DeauthenticateResponse)
|
||||
err := c.cc.Invoke(ctx, "/controller.api.services.v1.AuthenticationService/Deauthenticate", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuthenticationServiceServer is the server API for AuthenticationService service.
|
||||
type AuthenticationServiceServer interface {
|
||||
// Authenticate validates credentials provided and returns an auth token.
|
||||
Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error)
|
||||
// Logout terminates a user's current session.
|
||||
Deauthenticate(context.Context, *DeauthenticateRequest) (*DeauthenticateResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedAuthenticationServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedAuthenticationServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedAuthenticationServiceServer) Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
|
||||
}
|
||||
func (*UnimplementedAuthenticationServiceServer) Deauthenticate(context.Context, *DeauthenticateRequest) (*DeauthenticateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Deauthenticate not implemented")
|
||||
}
|
||||
|
||||
func RegisterAuthenticationServiceServer(s *grpc.Server, srv AuthenticationServiceServer) {
|
||||
s.RegisterService(&_AuthenticationService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _AuthenticationService_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthenticateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthenticationServiceServer).Authenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/controller.api.services.v1.AuthenticationService/Authenticate",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthenticationServiceServer).Authenticate(ctx, req.(*AuthenticateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthenticationService_Deauthenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeauthenticateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthenticationServiceServer).Deauthenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/controller.api.services.v1.AuthenticationService/Deauthenticate",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthenticationServiceServer).Deauthenticate(ctx, req.(*DeauthenticateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _AuthenticationService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "controller.api.services.v1.AuthenticationService",
|
||||
HandlerType: (*AuthenticationServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Authenticate",
|
||||
Handler: _AuthenticationService_Authenticate_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Deauthenticate",
|
||||
Handler: _AuthenticationService_Deauthenticate_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "controller/api/services/v1/authenticate_service.proto",
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: controller/api/services/v1/authenticate_service.proto
|
||||
|
||||
/*
|
||||
Package services is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/descriptor"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = descriptor.ForMessage
|
||||
|
||||
func request_AuthenticationService_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, client AuthenticationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["auth_method_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auth_method_id")
|
||||
}
|
||||
|
||||
protoReq.AuthMethodId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auth_method_id", err)
|
||||
}
|
||||
|
||||
msg, err := client.Authenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_AuthenticationService_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, server AuthenticationServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["auth_method_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auth_method_id")
|
||||
}
|
||||
|
||||
protoReq.AuthMethodId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auth_method_id", err)
|
||||
}
|
||||
|
||||
msg, err := server.Authenticate(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_AuthenticationService_Deauthenticate_0(ctx context.Context, marshaler runtime.Marshaler, client AuthenticationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeauthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
msg, err := client.Deauthenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_AuthenticationService_Deauthenticate_0(ctx context.Context, marshaler runtime.Marshaler, server AuthenticationServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeauthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
msg, err := server.Deauthenticate(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterAuthenticationServiceHandlerServer registers the http handlers for service AuthenticationService to "mux".
|
||||
// UnaryRPC :call AuthenticationServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
func RegisterAuthenticationServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthenticationServiceServer) error {
|
||||
|
||||
mux.Handle("POST", pattern_AuthenticationService_Authenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_AuthenticationService_Authenticate_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthenticationService_Authenticate_0(ctx, mux, outboundMarshaler, w, req, response_AuthenticationService_Authenticate_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_AuthenticationService_Deauthenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_AuthenticationService_Deauthenticate_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthenticationService_Deauthenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAuthenticationServiceHandlerFromEndpoint is same as RegisterAuthenticationServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterAuthenticationServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterAuthenticationServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterAuthenticationServiceHandler registers the http handlers for service AuthenticationService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterAuthenticationServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterAuthenticationServiceHandlerClient(ctx, mux, NewAuthenticationServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterAuthenticationServiceHandlerClient registers the http handlers for service AuthenticationService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthenticationServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthenticationServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "AuthenticationServiceClient" to call the correct interceptors.
|
||||
func RegisterAuthenticationServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthenticationServiceClient) error {
|
||||
|
||||
mux.Handle("POST", pattern_AuthenticationService_Authenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AuthenticationService_Authenticate_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthenticationService_Authenticate_0(ctx, mux, outboundMarshaler, w, req, response_AuthenticationService_Authenticate_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_AuthenticationService_Deauthenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AuthenticationService_Deauthenticate_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthenticationService_Deauthenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type response_AuthenticationService_Authenticate_0 struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
func (m response_AuthenticationService_Authenticate_0) XXX_ResponseBody() interface{} {
|
||||
response := m.Message.(*AuthenticateResponse)
|
||||
return response.Item
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_AuthenticationService_Authenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1", "orgs", "org_id", "auth-methods", "auth_method_id"}, "authenticate", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_AuthenticationService_Deauthenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "orgs", "org_id"}, "deauthenticate", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_AuthenticationService_Authenticate_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_AuthenticationService_Deauthenticate_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
context "context"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
|
||||
authtokens "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/authtokens"
|
||||
scopes "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/scopes"
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
grpc "google.golang.org/grpc"
|
||||
@@ -229,267 +228,6 @@ func (x *ListOrgsResponse) GetItems() []*scopes.Org {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PasswordCredential struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
LoginName string `protobuf:"bytes,1,opt,name=login_name,json=loginName,proto3" json:"login_name,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PasswordCredential) Reset() {
|
||||
*x = PasswordCredential{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PasswordCredential) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PasswordCredential) ProtoMessage() {}
|
||||
|
||||
func (x *PasswordCredential) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PasswordCredential.ProtoReflect.Descriptor instead.
|
||||
func (*PasswordCredential) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_org_service_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *PasswordCredential) GetLoginName() string {
|
||||
if x != nil {
|
||||
return x.LoginName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PasswordCredential) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthenticateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
|
||||
// The id to the authmethod in the system being used for authentication. The auth method must be in the org
|
||||
// being logged in to.
|
||||
AuthMethodId string `protobuf:"bytes,2,opt,name=auth_method_id,json=authMethodId,proto3" json:"auth_method_id,omitempty"`
|
||||
// This can be "cookie" or "token". If not provided, "token" will be used. For now only type "token" is returned.
|
||||
TokenType string `protobuf:"bytes,3,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"`
|
||||
PasswordCredential *PasswordCredential `protobuf:"bytes,4,opt,name=password_credential,json=passwordCredential,proto3" json:"password_credential,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) Reset() {
|
||||
*x = AuthenticateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthenticateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *AuthenticateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthenticateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*AuthenticateRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_org_service_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetOrgId() string {
|
||||
if x != nil {
|
||||
return x.OrgId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetAuthMethodId() string {
|
||||
if x != nil {
|
||||
return x.AuthMethodId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetTokenType() string {
|
||||
if x != nil {
|
||||
return x.TokenType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthenticateRequest) GetPasswordCredential() *PasswordCredential {
|
||||
if x != nil {
|
||||
return x.PasswordCredential
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthenticateResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Item *authtokens.AuthToken `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) Reset() {
|
||||
*x = AuthenticateResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthenticateResponse) ProtoMessage() {}
|
||||
|
||||
func (x *AuthenticateResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthenticateResponse.ProtoReflect.Descriptor instead.
|
||||
func (*AuthenticateResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_org_service_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *AuthenticateResponse) GetItem() *authtokens.AuthToken {
|
||||
if x != nil {
|
||||
return x.Item
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeauthenticateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
OrgId string `protobuf:"bytes,1,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DeauthenticateRequest) Reset() {
|
||||
*x = DeauthenticateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeauthenticateRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeauthenticateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeauthenticateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeauthenticateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeauthenticateRequest) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_org_service_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *DeauthenticateRequest) GetOrgId() string {
|
||||
if x != nil {
|
||||
return x.OrgId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeauthenticateResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *DeauthenticateResponse) Reset() {
|
||||
*x = DeauthenticateResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeauthenticateResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeauthenticateResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeauthenticateResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_api_services_v1_org_service_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeauthenticateResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeauthenticateResponse) Descriptor() ([]byte, []int) {
|
||||
return file_controller_api_services_v1_org_service_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
var File_controller_api_services_v1_org_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_api_services_v1_org_service_proto_rawDesc = []byte{
|
||||
@@ -505,103 +243,42 @@ var file_controller_api_services_v1_org_service_proto_rawDesc = []byte{
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
|
||||
0x2f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x36, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x61,
|
||||
0x75, 0x74, 0x68, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x33, 0x0a, 0x0d,
|
||||
0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x69, 0x65,
|
||||
0x77, 0x22, 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f,
|
||||
0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x22, 0x25, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x51, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4f,
|
||||
0x72, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x4f, 0x72, 0x67, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x4f, 0x0a, 0x12, 0x50, 0x61,
|
||||
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xd2, 0x01, 0x0a, 0x13,
|
||||
0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x61, 0x75,
|
||||
0x74, 0x68, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x49, 0x64,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12,
|
||||
0x5f, 0x0a, 0x13, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x33, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74,
|
||||
0x4f, 0x72, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f,
|
||||
0x72, 0x67, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x25, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x4f, 0x72, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x76,
|
||||
0x69, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22,
|
||||
0x51, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63,
|
||||
0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x52, 0x05, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x73, 0x32, 0xae, 0x02, 0x0a, 0x0a, 0x4f, 0x72, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x12, 0x92, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x12, 0x29, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f,
|
||||
0x72, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x12, 0x70, 0x61,
|
||||
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
|
||||
0x22, 0x5d, 0x0a, 0x14, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22,
|
||||
0x2e, 0x0a, 0x15, 0x44, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x22,
|
||||
0x18, 0x0a, 0x16, 0x44, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf7, 0x05, 0x0a, 0x0a, 0x4f, 0x72,
|
||||
0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74,
|
||||
0x4f, 0x72, 0x67, 0x12, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f,
|
||||
0x72, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x15, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64,
|
||||
0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x13, 0x12, 0x11, 0x47, 0x65, 0x74, 0x73,
|
||||
0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x12, 0x8a, 0x01,
|
||||
0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x92, 0x41, 0x10, 0x12, 0x0e, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x4f, 0x72, 0x67, 0x73, 0x12, 0xea, 0x01, 0x0a, 0x0c, 0x41,
|
||||
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x77,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92,
|
||||
0x41, 0x45, 0x12, 0x43, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x20, 0x4f, 0x72,
|
||||
0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x61,
|
||||
0x6e, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x12, 0xd9, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x61, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x60, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x6f,
|
||||
0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x64, 0x65, 0x61,
|
||||
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x92, 0x41, 0x35, 0x12, 0x33,
|
||||
0x44, 0x65, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x61,
|
||||
0x6e, 0x20, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6e, 0x20, 0x4f,
|
||||
0x72, 0x67, 0x2e, 0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x0d, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x92, 0x41, 0x13, 0x12, 0x11, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67,
|
||||
0x6c, 0x65, 0x20, 0x4f, 0x72, 0x67, 0x12, 0x8a, 0x01, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4f,
|
||||
0x72, 0x67, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x4f, 0x72, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x92, 0x41, 0x10, 0x12, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x4f,
|
||||
0x72, 0x67, 0x73, 0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63,
|
||||
0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
||||
0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61,
|
||||
@@ -621,38 +298,26 @@ func file_controller_api_services_v1_org_service_proto_rawDescGZIP() []byte {
|
||||
return file_controller_api_services_v1_org_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_controller_api_services_v1_org_service_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
var file_controller_api_services_v1_org_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_controller_api_services_v1_org_service_proto_goTypes = []interface{}{
|
||||
(*GetOrgRequest)(nil), // 0: controller.api.services.v1.GetOrgRequest
|
||||
(*GetOrgResponse)(nil), // 1: controller.api.services.v1.GetOrgResponse
|
||||
(*ListOrgsRequest)(nil), // 2: controller.api.services.v1.ListOrgsRequest
|
||||
(*ListOrgsResponse)(nil), // 3: controller.api.services.v1.ListOrgsResponse
|
||||
(*PasswordCredential)(nil), // 4: controller.api.services.v1.PasswordCredential
|
||||
(*AuthenticateRequest)(nil), // 5: controller.api.services.v1.AuthenticateRequest
|
||||
(*AuthenticateResponse)(nil), // 6: controller.api.services.v1.AuthenticateResponse
|
||||
(*DeauthenticateRequest)(nil), // 7: controller.api.services.v1.DeauthenticateRequest
|
||||
(*DeauthenticateResponse)(nil), // 8: controller.api.services.v1.DeauthenticateResponse
|
||||
(*scopes.Org)(nil), // 9: controller.api.resources.scopes.v1.Org
|
||||
(*authtokens.AuthToken)(nil), // 10: controller.api.resources.authtokens.v1.AuthToken
|
||||
(*GetOrgRequest)(nil), // 0: controller.api.services.v1.GetOrgRequest
|
||||
(*GetOrgResponse)(nil), // 1: controller.api.services.v1.GetOrgResponse
|
||||
(*ListOrgsRequest)(nil), // 2: controller.api.services.v1.ListOrgsRequest
|
||||
(*ListOrgsResponse)(nil), // 3: controller.api.services.v1.ListOrgsResponse
|
||||
(*scopes.Org)(nil), // 4: controller.api.resources.scopes.v1.Org
|
||||
}
|
||||
var file_controller_api_services_v1_org_service_proto_depIdxs = []int32{
|
||||
9, // 0: controller.api.services.v1.GetOrgResponse.item:type_name -> controller.api.resources.scopes.v1.Org
|
||||
9, // 1: controller.api.services.v1.ListOrgsResponse.items:type_name -> controller.api.resources.scopes.v1.Org
|
||||
4, // 2: controller.api.services.v1.AuthenticateRequest.password_credential:type_name -> controller.api.services.v1.PasswordCredential
|
||||
10, // 3: controller.api.services.v1.AuthenticateResponse.item:type_name -> controller.api.resources.authtokens.v1.AuthToken
|
||||
0, // 4: controller.api.services.v1.OrgService.GetOrg:input_type -> controller.api.services.v1.GetOrgRequest
|
||||
2, // 5: controller.api.services.v1.OrgService.ListOrgs:input_type -> controller.api.services.v1.ListOrgsRequest
|
||||
5, // 6: controller.api.services.v1.OrgService.Authenticate:input_type -> controller.api.services.v1.AuthenticateRequest
|
||||
7, // 7: controller.api.services.v1.OrgService.Deauthenticate:input_type -> controller.api.services.v1.DeauthenticateRequest
|
||||
1, // 8: controller.api.services.v1.OrgService.GetOrg:output_type -> controller.api.services.v1.GetOrgResponse
|
||||
3, // 9: controller.api.services.v1.OrgService.ListOrgs:output_type -> controller.api.services.v1.ListOrgsResponse
|
||||
6, // 10: controller.api.services.v1.OrgService.Authenticate:output_type -> controller.api.services.v1.AuthenticateResponse
|
||||
8, // 11: controller.api.services.v1.OrgService.Deauthenticate:output_type -> controller.api.services.v1.DeauthenticateResponse
|
||||
8, // [8:12] is the sub-list for method output_type
|
||||
4, // [4:8] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
4, // 0: controller.api.services.v1.GetOrgResponse.item:type_name -> controller.api.resources.scopes.v1.Org
|
||||
4, // 1: controller.api.services.v1.ListOrgsResponse.items:type_name -> controller.api.resources.scopes.v1.Org
|
||||
0, // 2: controller.api.services.v1.OrgService.GetOrg:input_type -> controller.api.services.v1.GetOrgRequest
|
||||
2, // 3: controller.api.services.v1.OrgService.ListOrgs:input_type -> controller.api.services.v1.ListOrgsRequest
|
||||
1, // 4: controller.api.services.v1.OrgService.GetOrg:output_type -> controller.api.services.v1.GetOrgResponse
|
||||
3, // 5: controller.api.services.v1.OrgService.ListOrgs:output_type -> controller.api.services.v1.ListOrgsResponse
|
||||
4, // [4:6] is the sub-list for method output_type
|
||||
2, // [2:4] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_controller_api_services_v1_org_service_proto_init() }
|
||||
@@ -709,66 +374,6 @@ func file_controller_api_services_v1_org_service_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_org_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PasswordCredential); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_org_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthenticateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_org_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AuthenticateResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_org_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeauthenticateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_api_services_v1_org_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeauthenticateResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -776,7 +381,7 @@ func file_controller_api_services_v1_org_service_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_controller_api_services_v1_org_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 9,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
@@ -808,10 +413,6 @@ type OrgServiceClient interface {
|
||||
GetOrg(ctx context.Context, in *GetOrgRequest, opts ...grpc.CallOption) (*GetOrgResponse, error)
|
||||
// ListOrgs returns a list of stored orgs which exist in watchtower.
|
||||
ListOrgs(ctx context.Context, in *ListOrgsRequest, opts ...grpc.CallOption) (*ListOrgsResponse, error)
|
||||
// Authenticate validates credentials provided and returns an auth token.
|
||||
Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error)
|
||||
// Logout terminates a user's current session.
|
||||
Deauthenticate(ctx context.Context, in *DeauthenticateRequest, opts ...grpc.CallOption) (*DeauthenticateResponse, error)
|
||||
}
|
||||
|
||||
type orgServiceClient struct {
|
||||
@@ -840,24 +441,6 @@ func (c *orgServiceClient) ListOrgs(ctx context.Context, in *ListOrgsRequest, op
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *orgServiceClient) Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error) {
|
||||
out := new(AuthenticateResponse)
|
||||
err := c.cc.Invoke(ctx, "/controller.api.services.v1.OrgService/Authenticate", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *orgServiceClient) Deauthenticate(ctx context.Context, in *DeauthenticateRequest, opts ...grpc.CallOption) (*DeauthenticateResponse, error) {
|
||||
out := new(DeauthenticateResponse)
|
||||
err := c.cc.Invoke(ctx, "/controller.api.services.v1.OrgService/Deauthenticate", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// OrgServiceServer is the server API for OrgService service.
|
||||
type OrgServiceServer interface {
|
||||
// GetOrg returns a stored Org if present. The provided request
|
||||
@@ -866,10 +449,6 @@ type OrgServiceServer interface {
|
||||
GetOrg(context.Context, *GetOrgRequest) (*GetOrgResponse, error)
|
||||
// ListOrgs returns a list of stored orgs which exist in watchtower.
|
||||
ListOrgs(context.Context, *ListOrgsRequest) (*ListOrgsResponse, error)
|
||||
// Authenticate validates credentials provided and returns an auth token.
|
||||
Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error)
|
||||
// Logout terminates a user's current session.
|
||||
Deauthenticate(context.Context, *DeauthenticateRequest) (*DeauthenticateResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedOrgServiceServer can be embedded to have forward compatible implementations.
|
||||
@@ -882,12 +461,6 @@ func (*UnimplementedOrgServiceServer) GetOrg(context.Context, *GetOrgRequest) (*
|
||||
func (*UnimplementedOrgServiceServer) ListOrgs(context.Context, *ListOrgsRequest) (*ListOrgsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListOrgs not implemented")
|
||||
}
|
||||
func (*UnimplementedOrgServiceServer) Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
|
||||
}
|
||||
func (*UnimplementedOrgServiceServer) Deauthenticate(context.Context, *DeauthenticateRequest) (*DeauthenticateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Deauthenticate not implemented")
|
||||
}
|
||||
|
||||
func RegisterOrgServiceServer(s *grpc.Server, srv OrgServiceServer) {
|
||||
s.RegisterService(&_OrgService_serviceDesc, srv)
|
||||
@@ -929,42 +502,6 @@ func _OrgService_ListOrgs_Handler(srv interface{}, ctx context.Context, dec func
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _OrgService_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthenticateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(OrgServiceServer).Authenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/controller.api.services.v1.OrgService/Authenticate",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(OrgServiceServer).Authenticate(ctx, req.(*AuthenticateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _OrgService_Deauthenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeauthenticateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(OrgServiceServer).Deauthenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/controller.api.services.v1.OrgService/Deauthenticate",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(OrgServiceServer).Deauthenticate(ctx, req.(*DeauthenticateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _OrgService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "controller.api.services.v1.OrgService",
|
||||
HandlerType: (*OrgServiceServer)(nil),
|
||||
@@ -977,14 +514,6 @@ var _OrgService_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "ListOrgs",
|
||||
Handler: _OrgService_ListOrgs_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Authenticate",
|
||||
Handler: _OrgService_Authenticate_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Deauthenticate",
|
||||
Handler: _OrgService_Deauthenticate_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "controller/api/services/v1/org_service.proto",
|
||||
|
||||
@@ -139,130 +139,6 @@ func local_request_OrgService_ListOrgs_0(ctx context.Context, marshaler runtime.
|
||||
|
||||
}
|
||||
|
||||
func request_OrgService_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, client OrgServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
msg, err := client.Authenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_OrgService_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, server OrgServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
msg, err := server.Authenticate(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_OrgService_Deauthenticate_0(ctx context.Context, marshaler runtime.Marshaler, client OrgServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeauthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
msg, err := client.Deauthenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_OrgService_Deauthenticate_0(ctx context.Context, marshaler runtime.Marshaler, server OrgServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeauthenticateRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["org_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
|
||||
}
|
||||
|
||||
protoReq.OrgId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
|
||||
}
|
||||
|
||||
msg, err := server.Deauthenticate(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterOrgServiceHandlerServer registers the http handlers for service OrgService to "mux".
|
||||
// UnaryRPC :call OrgServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
@@ -308,46 +184,6 @@ func RegisterOrgServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux,
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_OrgService_Authenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_OrgService_Authenticate_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_OrgService_Authenticate_0(ctx, mux, outboundMarshaler, w, req, response_OrgService_Authenticate_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_OrgService_Deauthenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_OrgService_Deauthenticate_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_OrgService_Deauthenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -429,46 +265,6 @@ func RegisterOrgServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux,
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_OrgService_Authenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_OrgService_Authenticate_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_OrgService_Authenticate_0(ctx, mux, outboundMarshaler, w, req, response_OrgService_Authenticate_0{resp}, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_OrgService_Deauthenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_OrgService_Deauthenticate_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_OrgService_Deauthenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -481,31 +277,14 @@ func (m response_OrgService_GetOrg_0) XXX_ResponseBody() interface{} {
|
||||
return response.Item
|
||||
}
|
||||
|
||||
type response_OrgService_Authenticate_0 struct {
|
||||
proto.Message
|
||||
}
|
||||
|
||||
func (m response_OrgService_Authenticate_0) XXX_ResponseBody() interface{} {
|
||||
response := m.Message.(*AuthenticateResponse)
|
||||
return response.Item
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_OrgService_GetOrg_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "orgs", "id"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_OrgService_ListOrgs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "orgs"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_OrgService_Authenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "orgs", "org_id"}, "authenticate", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_OrgService_Deauthenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "orgs", "org_id"}, "deauthenticate", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_OrgService_GetOrg_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_OrgService_ListOrgs_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_OrgService_Authenticate_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_OrgService_Deauthenticate_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
@@ -627,9 +627,8 @@ type AddRolePrincipalsRequest struct {
|
||||
RoleId string `protobuf:"bytes,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"`
|
||||
// The version ensures the role hasn't changed since it was last retrieved and if
|
||||
// it has the request will fail.
|
||||
Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
UserIds []string `protobuf:"bytes,5,rep,name=user_ids,proto3" json:"user_ids,omitempty"`
|
||||
GroupIds []string `protobuf:"bytes,6,rep,name=group_ids,proto3" json:"group_ids,omitempty"`
|
||||
Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
PrincipalIds []string `protobuf:"bytes,5,rep,name=principal_ids,proto3" json:"principal_ids,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AddRolePrincipalsRequest) Reset() {
|
||||
@@ -692,16 +691,9 @@ func (x *AddRolePrincipalsRequest) GetVersion() *wrappers.UInt32Value {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AddRolePrincipalsRequest) GetUserIds() []string {
|
||||
func (x *AddRolePrincipalsRequest) GetPrincipalIds() []string {
|
||||
if x != nil {
|
||||
return x.UserIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AddRolePrincipalsRequest) GetGroupIds() []string {
|
||||
if x != nil {
|
||||
return x.GroupIds
|
||||
return x.PrincipalIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -763,9 +755,8 @@ type SetRolePrincipalsRequest struct {
|
||||
RoleId string `protobuf:"bytes,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"`
|
||||
// The version ensures the role hasn't changed since it was last retrieved and if
|
||||
// it has the request will fail.
|
||||
Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
UserIds []string `protobuf:"bytes,5,rep,name=user_ids,proto3" json:"user_ids,omitempty"`
|
||||
GroupIds []string `protobuf:"bytes,6,rep,name=group_ids,proto3" json:"group_ids,omitempty"`
|
||||
Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
PrincipalIds []string `protobuf:"bytes,5,rep,name=principal_ids,proto3" json:"principal_ids,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SetRolePrincipalsRequest) Reset() {
|
||||
@@ -828,16 +819,9 @@ func (x *SetRolePrincipalsRequest) GetVersion() *wrappers.UInt32Value {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SetRolePrincipalsRequest) GetUserIds() []string {
|
||||
func (x *SetRolePrincipalsRequest) GetPrincipalIds() []string {
|
||||
if x != nil {
|
||||
return x.UserIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SetRolePrincipalsRequest) GetGroupIds() []string {
|
||||
if x != nil {
|
||||
return x.GroupIds
|
||||
return x.PrincipalIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -899,9 +883,8 @@ type RemoveRolePrincipalsRequest struct {
|
||||
RoleId string `protobuf:"bytes,3,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"`
|
||||
// The version ensures the role hasn't changed since it was last retrieved and if
|
||||
// it has the request will fail.
|
||||
Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
UserIds []string `protobuf:"bytes,5,rep,name=user_ids,proto3" json:"user_ids,omitempty"`
|
||||
GroupIds []string `protobuf:"bytes,6,rep,name=group_ids,proto3" json:"group_ids,omitempty"`
|
||||
Version *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
|
||||
PrincipalIds []string `protobuf:"bytes,5,rep,name=principal_ids,proto3" json:"principal_ids,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RemoveRolePrincipalsRequest) Reset() {
|
||||
@@ -964,16 +947,9 @@ func (x *RemoveRolePrincipalsRequest) GetVersion() *wrappers.UInt32Value {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RemoveRolePrincipalsRequest) GetUserIds() []string {
|
||||
func (x *RemoveRolePrincipalsRequest) GetPrincipalIds() []string {
|
||||
if x != nil {
|
||||
return x.UserIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RemoveRolePrincipalsRequest) GetGroupIds() []string {
|
||||
if x != nil {
|
||||
return x.GroupIds
|
||||
return x.PrincipalIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1493,7 +1469,7 @@ var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
|
||||
0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x22, 0xdb, 0x01, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x52,
|
||||
0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x22, 0xc7, 0x01, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70,
|
||||
@@ -1503,311 +1479,307 @@ var file_controller_api_services_v1_role_service_proto_rawDesc = []byte{
|
||||
0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70,
|
||||
0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75,
|
||||
0x70, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x58, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x70,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64,
|
||||
0x73, 0x22, 0x58, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e,
|
||||
0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b,
|
||||
0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xc7, 0x01, 0x0a, 0x18,
|
||||
0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17,
|
||||
0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33,
|
||||
0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x24, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73,
|
||||
0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x58, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22,
|
||||
0xdb, 0x01, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06,
|
||||
0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72,
|
||||
0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55,
|
||||
0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18,
|
||||
0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x58, 0x0a,
|
||||
0x19, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74,
|
||||
0xca, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72,
|
||||
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36,
|
||||
0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x5b, 0x0a, 0x1c,
|
||||
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xb5, 0x01, 0x0a, 0x14, 0x41, 0x64,
|
||||
0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70,
|
||||
0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49,
|
||||
0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x73, 0x22, 0x54, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74,
|
||||
0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xde, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a,
|
||||
0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x67,
|
||||
0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x73, 0x22, 0x5b, 0x0a, 0x1c, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73,
|
||||
0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xb5, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12,
|
||||
0x36, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22,
|
||||
0x54, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xb5, 0x01, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15,
|
||||
0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18,
|
||||
0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a,
|
||||
0x15, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x22, 0xb5, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06,
|
||||
0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72,
|
||||
0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55,
|
||||
0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x15, 0x53,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x22, 0xb8, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a,
|
||||
0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f,
|
||||
0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x07,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x57, 0x0a, 0x18,
|
||||
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xe4, 0x18, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xe1, 0x01, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7d, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x60, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72,
|
||||
0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
|
||||
0x5a, 0x3a, 0x12, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72,
|
||||
0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b,
|
||||
0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74,
|
||||
0x65, 0x6d, 0x92, 0x41, 0x14, 0x12, 0x12, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69,
|
||||
0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xce, 0x01, 0x0a, 0x09, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xb8, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72,
|
||||
0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64,
|
||||
0x12, 0x36, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73,
|
||||
0x22, 0x57, 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xe4, 0x18, 0x0a, 0x0b, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xe1, 0x01, 0x0a, 0x07, 0x47, 0x65,
|
||||
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4a, 0x12, 0x17, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5a, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67,
|
||||
0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x92, 0x41, 0x11, 0x12, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x73,
|
||||
0x20, 0x61, 0x6c, 0x6c, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xf0, 0x01, 0x0a, 0x0a, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x62, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x5a, 0x3b, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72,
|
||||
0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b,
|
||||
0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x92, 0x41, 0x17, 0x12, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20,
|
||||
0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xf3, 0x01,
|
||||
0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, 0x01, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x6c, 0x32, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b,
|
||||
0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69,
|
||||
0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x5a, 0x40, 0x32, 0x32, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x92, 0x41, 0x10, 0x12, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x12, 0xda, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44,
|
||||
0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x6d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x54, 0x2a, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f,
|
||||
0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x34, 0x2a, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x6f,
|
||||
0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69,
|
||||
0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x92, 0x41, 0x10,
|
||||
0x12, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x12, 0xbf, 0x02, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e,
|
||||
0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0xbc, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8e, 0x01, 0x22, 0x30, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x61, 0x64, 0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x3a,
|
||||
0x01, 0x2a, 0x5a, 0x51, 0x22, 0x46, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b,
|
||||
0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73,
|
||||
0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64,
|
||||
0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x3a, 0x01, 0x2a, 0x62,
|
||||
0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x24, 0x12, 0x22,
|
||||
0x41, 0x64, 0x64, 0x73, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f,
|
||||
0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x12, 0xfe, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72,
|
||||
0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69,
|
||||
0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfb, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8e, 0x01, 0x22,
|
||||
0x30, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69,
|
||||
0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69,
|
||||
0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c,
|
||||
0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x51, 0x22, 0x46, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7d,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x60, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f,
|
||||
0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x3a, 0x12, 0x32, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a,
|
||||
0x73, 0x65, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x3a, 0x01,
|
||||
0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x63,
|
||||
0x12, 0x61, 0x53, 0x65, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f,
|
||||
0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e,
|
||||
0x79, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x20, 0x74, 0x68, 0x61,
|
||||
0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,
|
||||
0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x2e, 0x12, 0xe2, 0x02, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x37, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69,
|
||||
0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0xd6, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x94, 0x01, 0x22, 0x33, 0x2f, 0x76, 0x31, 0x2f, 0x6f,
|
||||
0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x3a, 0x01,
|
||||
0x2a, 0x5a, 0x54, 0x22, 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f,
|
||||
0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f,
|
||||
0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x3a, 0x01,
|
||||
0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x38,
|
||||
0x12, 0x36, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70,
|
||||
0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e,
|
||||
0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d,
|
||||
0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x12, 0x9e, 0x02, 0x0a, 0x0d, 0x41, 0x64, 0x64,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0xa7, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x86, 0x01, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x6f,
|
||||
0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64,
|
||||
0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x4d, 0x22, 0x42, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
||||
0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c,
|
||||
0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73,
|
||||
0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92,
|
||||
0x41, 0x17, 0x12, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20,
|
||||
0x74, 0x6f, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0xda, 0x02, 0x0a, 0x0d, 0x53, 0x65,
|
||||
0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x14, 0x12, 0x12, 0x47, 0x65, 0x74, 0x73, 0x20,
|
||||
0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xce, 0x01,
|
||||
0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4a,
|
||||
0x12, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5a, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x92, 0x41, 0x11, 0x12, 0x0f, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xf0,
|
||||
0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0xe3, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x86, 0x01, 0x22, 0x2c, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65,
|
||||
0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x4d, 0x22, 0x42, 0x2f,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x62, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f,
|
||||
0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x5a, 0x3b, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x17, 0x12, 0x15, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x12, 0xf3, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x85, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6c, 0x32, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72,
|
||||
0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x5a, 0x40, 0x32, 0x32,
|
||||
0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64,
|
||||
0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69,
|
||||
0x64, 0x7d, 0x3a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x10, 0x12, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73,
|
||||
0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xda, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
|
||||
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x54, 0x2a, 0x1c, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x34, 0x2a, 0x32, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x92, 0x41, 0x53, 0x12, 0x51, 0x53, 0x65, 0x74, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20,
|
||||
0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20,
|
||||
0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70, 0x65,
|
||||
0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x12, 0xb3, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x76,
|
||||
0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64,
|
||||
0x7d, 0x92, 0x41, 0x10, 0x12, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x12, 0xbf, 0x02, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65,
|
||||
0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50,
|
||||
0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64,
|
||||
0x64, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbc, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8e,
|
||||
0x01, 0x22, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6c, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x51, 0x22, 0x46, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72,
|
||||
0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64,
|
||||
0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64,
|
||||
0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73,
|
||||
0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92,
|
||||
0x41, 0x24, 0x12, 0x22, 0x41, 0x64, 0x64, 0x73, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20, 0x61,
|
||||
0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f, 0x20,
|
||||
0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0xfe, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x34, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfb, 0x01, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x8e, 0x01, 0x22, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f,
|
||||
0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x61, 0x6c, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x51, 0x22, 0x46, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x92, 0x41, 0x63, 0x12, 0x61, 0x53, 0x65, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x73, 0x20,
|
||||
0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x74, 0x6f,
|
||||
0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e,
|
||||
0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73,
|
||||
0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x70,
|
||||
0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x12, 0xe2, 0x02, 0x0a, 0x14, 0x52, 0x65, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73,
|
||||
0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x8c, 0x01,
|
||||
0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f,
|
||||
0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c,
|
||||
0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0xd6, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x94, 0x01, 0x22, 0x33, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x54, 0x22, 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67,
|
||||
0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x92, 0x41, 0x38, 0x12, 0x36, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x55, 0x73, 0x65, 0x72,
|
||||
0x73, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20,
|
||||
0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x52, 0x6f, 0x6c, 0x65, 0x2e, 0x12, 0x9e, 0x02, 0x0a,
|
||||
0x0d, 0x41, 0x64, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x30,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64,
|
||||
0x64, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0xa7, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x86, 0x01, 0x22, 0x2c, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x4d,
|
||||
0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72,
|
||||
0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f,
|
||||
0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x61, 0x64, 0x64, 0x2d, 0x67, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69,
|
||||
0x74, 0x65, 0x6d, 0x92, 0x41, 0x17, 0x12, 0x15, 0x41, 0x64, 0x64, 0x73, 0x20, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0xda, 0x02,
|
||||
0x0a, 0x0d, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12,
|
||||
0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74,
|
||||
0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe3, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x86, 0x01, 0x22, 0x2c,
|
||||
0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64,
|
||||
0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64,
|
||||
0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a,
|
||||
0x4d, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67,
|
||||
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70,
|
||||
0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73,
|
||||
0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x2d, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04,
|
||||
0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x53, 0x12, 0x51, 0x53, 0x65, 0x74, 0x20, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2c, 0x20,
|
||||
0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74,
|
||||
0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x12, 0xb3, 0x02, 0x0a, 0x10, 0x52,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12,
|
||||
0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d,
|
||||
0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x47, 0x72, 0x61, 0x6e,
|
||||
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x8c, 0x01, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b,
|
||||
0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72,
|
||||
0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x50, 0x22, 0x45, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x6f, 0x72, 0x67, 0x73, 0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x3a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74,
|
||||
0x73, 0x3a, 0x01, 0x2a, 0x5a, 0x50, 0x22, 0x45, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x67, 0x73,
|
||||
0x2f, 0x7b, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a,
|
||||
0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2d, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x3a, 0x01, 0x2a,
|
||||
0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x92, 0x41, 0x1d, 0x12,
|
||||
0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x20,
|
||||
0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2e, 0x42, 0x4f, 0x5a, 0x4d,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x2f,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x73, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d,
|
||||
0x92, 0x41, 0x1d, 0x12, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x20, 0x67, 0x72, 0x61,
|
||||
0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x2e,
|
||||
0x42, 0x4f, 0x5a, 0x4d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x74, 0x6f,
|
||||
0x77, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e,
|
||||
0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -3,6 +3,7 @@ package iam
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/db"
|
||||
"github.com/hashicorp/watchtower/internal/oplog"
|
||||
@@ -12,10 +13,14 @@ import (
|
||||
// groupIds) to a role (roleId). The role's current db version must match the
|
||||
// roleVersion or an error will be returned. The list of current PrincipalRoles
|
||||
// after the adds will be returned on success.
|
||||
func (r *Repository) AddPrincipalRoles(ctx context.Context, roleId string, roleVersion uint32, userIds, groupIds []string, opt ...Option) ([]PrincipalRole, error) {
|
||||
func (r *Repository) AddPrincipalRoles(ctx context.Context, roleId string, roleVersion uint32, principalIds []string, opt ...Option) ([]PrincipalRole, error) {
|
||||
if roleId == "" {
|
||||
return nil, fmt.Errorf("add principal roles: missing role id: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
userIds, groupIds, err := splitPrincipals(principalIds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add principal roles: error parsing principals: %w", err)
|
||||
}
|
||||
if len(userIds) == 0 && len(groupIds) == 0 {
|
||||
return nil, fmt.Errorf("add principal roles: missing either user or groups to add: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
@@ -114,7 +119,7 @@ func (r *Repository) AddPrincipalRoles(ctx context.Context, roleId string, roleV
|
||||
// principals as need to reconcile the existing principals with the principals
|
||||
// requested. If both userIds and groupIds are empty, the principal roles will
|
||||
// be cleared.
|
||||
func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleVersion uint32, userIds, groupIds []string, opt ...Option) ([]PrincipalRole, int, error) {
|
||||
func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleVersion uint32, principalIds []string, opt ...Option) ([]PrincipalRole, int, error) {
|
||||
if roleId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set principal roles: missing role id: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
@@ -127,6 +132,10 @@ func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleV
|
||||
// it's "safe" to do this lookup outside the DoTx transaction because we
|
||||
// have a roleVersion so the principals can’t change without the version
|
||||
// changing.
|
||||
userIds, groupIds, err := splitPrincipals(principalIds)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set principal roles: error parsing principals: %w", err)
|
||||
}
|
||||
toSet, err := r.principalsToSet(ctx, &role, userIds, groupIds)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set principal roles: unable to determine set: %w", err)
|
||||
@@ -243,10 +252,14 @@ func (r *Repository) SetPrincipalRoles(ctx context.Context, roleId string, roleV
|
||||
// DeletePrincipalRoles principals (userIds and/or groupIds) from a role
|
||||
// (roleId). The role's current db version must match the roleVersion or an
|
||||
// error will be returned.
|
||||
func (r *Repository) DeletePrincipalRoles(ctx context.Context, roleId string, roleVersion uint32, userIds, groupIds []string, opt ...Option) (int, error) {
|
||||
func (r *Repository) DeletePrincipalRoles(ctx context.Context, roleId string, roleVersion uint32, principalIds []string, opt ...Option) (int, error) {
|
||||
if roleId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete principal roles: missing role id: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
userIds, groupIds, err := splitPrincipals(principalIds)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("remove principal roles: error parsing principals: %w", err)
|
||||
}
|
||||
if len(userIds) == 0 && len(groupIds) == 0 {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete principal roles: missing either user or groups to delete: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
@@ -441,3 +454,20 @@ func (r *Repository) principalsToSet(ctx context.Context, role *Role, userIds, g
|
||||
|
||||
return toSet, nil
|
||||
}
|
||||
|
||||
func splitPrincipals(principals []string) ([]string, []string, error) {
|
||||
var users, groups []string
|
||||
for _, principal := range principals {
|
||||
switch {
|
||||
case strings.HasPrefix(principal, UserPrefix):
|
||||
users = append(users, principal)
|
||||
// TODO: This needs to handle all of the kinds of group prefixes (sg_, dg_, etc.)
|
||||
case strings.HasPrefix(principal, GroupPrefix):
|
||||
groups = append(groups, principal)
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("invalid principal ID %q: %w", principal, db.ErrInvalidParameter)
|
||||
}
|
||||
}
|
||||
|
||||
return users, groups, nil
|
||||
}
|
||||
@@ -132,7 +132,8 @@ func TestRepository_AddPrincipalRoles(t *testing.T) {
|
||||
groupIds = append(groupIds, g.PublicId)
|
||||
}
|
||||
}
|
||||
got, err := repo.AddPrincipalRoles(context.Background(), roleId, tt.args.roleVersion, userIds, groupIds, tt.args.opt...)
|
||||
principalIds := append(userIds, groupIds...)
|
||||
got, err := repo.AddPrincipalRoles(context.Background(), roleId, tt.args.roleVersion, principalIds, tt.args.opt...)
|
||||
if tt.wantErr {
|
||||
require.Error(err)
|
||||
if tt.wantErrIs != nil {
|
||||
@@ -236,7 +237,7 @@ func TestRepository_ListPrincipalRoles(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
require.NoError(conn.Where("1=1").Delete(allocRole()).Error)
|
||||
require.NoError(conn.Where("public_id != ?", "r_default").Delete(allocRole()).Error)
|
||||
role := TestRole(t, conn, tt.createScopeId)
|
||||
userRoles := make([]string, 0, tt.createCnt)
|
||||
groupRoles := make([]string, 0, tt.createCnt)
|
||||
@@ -246,7 +247,8 @@ func TestRepository_ListPrincipalRoles(t *testing.T) {
|
||||
g := TestGroup(t, conn, tt.createScopeId)
|
||||
groupRoles = append(groupRoles, g.PublicId)
|
||||
}
|
||||
testRoles, err := repo.AddPrincipalRoles(context.Background(), role.PublicId, role.Version, userRoles, groupRoles, tt.args.opt...)
|
||||
principalIds := append(userRoles, groupRoles...)
|
||||
testRoles, err := repo.AddPrincipalRoles(context.Background(), role.PublicId, role.Version, principalIds, tt.args.opt...)
|
||||
require.NoError(err)
|
||||
assert.Equal(tt.createCnt, len(testRoles))
|
||||
|
||||
@@ -406,7 +408,8 @@ func TestRepository_DeletePrincipalRoles(t *testing.T) {
|
||||
groupIds = append(groupIds, g.PublicId)
|
||||
}
|
||||
}
|
||||
principalRoles, err := repo.AddPrincipalRoles(context.Background(), tt.args.role.PublicId, 1, userIds, groupIds, tt.args.opt...)
|
||||
principalIds := append(userIds, groupIds...)
|
||||
principalRoles, err := repo.AddPrincipalRoles(context.Background(), tt.args.role.PublicId, 1, principalIds, tt.args.opt...)
|
||||
require.NoError(err)
|
||||
assert.Equal(tt.args.createUserCnt+tt.args.createGroupCnt, len(principalRoles))
|
||||
|
||||
@@ -425,7 +428,8 @@ func TestRepository_DeletePrincipalRoles(t *testing.T) {
|
||||
default:
|
||||
roleId = tt.args.role.PublicId
|
||||
}
|
||||
deletedRows, err := repo.DeletePrincipalRoles(context.Background(), roleId, 2, deleteUserIds, deleteGroupIds, tt.args.opt...)
|
||||
principalIds = append(deleteUserIds, deleteGroupIds...)
|
||||
deletedRows, err := repo.DeletePrincipalRoles(context.Background(), roleId, 2, principalIds, tt.args.opt...)
|
||||
if tt.wantErr {
|
||||
assert.Error(err)
|
||||
assert.Equal(0, deletedRows)
|
||||
@@ -480,7 +484,7 @@ func TestRepository_SetPrincipalRoles(t *testing.T) {
|
||||
users := createUsersFn()
|
||||
grps := createGrpsFn()
|
||||
var err error
|
||||
_, err = repo.AddPrincipalRoles(context.Background(), role.PublicId, 1, users, grps)
|
||||
_, err = repo.AddPrincipalRoles(context.Background(), role.PublicId, 1, append(users, grps...))
|
||||
require.NoError(t, err)
|
||||
return users, grps
|
||||
}
|
||||
@@ -568,8 +572,8 @@ func TestRepository_SetPrincipalRoles(t *testing.T) {
|
||||
if tt.args.addToOrigGrps {
|
||||
tt.args.groupIds = append(tt.args.groupIds, origGrps...)
|
||||
}
|
||||
|
||||
got, affectedRows, err := repo.SetPrincipalRoles(context.Background(), tt.args.role.PublicId, tt.args.roleVersion, tt.args.userIds, tt.args.groupIds, tt.args.opt...)
|
||||
principalIds := append(tt.args.userIds, tt.args.groupIds...)
|
||||
got, affectedRows, err := repo.SetPrincipalRoles(context.Background(), tt.args.role.PublicId, tt.args.roleVersion, principalIds, tt.args.opt...)
|
||||
if tt.wantErr {
|
||||
require.Error(err)
|
||||
return
|
||||
@@ -619,7 +623,7 @@ func TestRepository_principalsToSet(t *testing.T) {
|
||||
users := createUsersFn()
|
||||
grps := createGrpsFn()
|
||||
role := TestRole(t, conn, proj.PublicId)
|
||||
_, err := repo.AddPrincipalRoles(context.Background(), role.PublicId, 1, users, grps)
|
||||
_, err := repo.AddPrincipalRoles(context.Background(), role.PublicId, 1, append(users, grps...))
|
||||
require.NoError(t, err)
|
||||
return role, users, grps
|
||||
}
|
||||
|
||||
@@ -351,3 +351,90 @@ func (r *Repository) ListRoleGrants(ctx context.Context, roleId string, opt ...O
|
||||
}
|
||||
return roleGrants, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GrantsForUser(ctx context.Context, userId string, opt ...Option) ([]perms.GrantPair, error) {
|
||||
if userId == "" {
|
||||
return nil, fmt.Errorf("get grants for user: missing user id: %w", db.ErrInvalidParameter)
|
||||
}
|
||||
|
||||
const (
|
||||
anonUser = `where public_id in ($1)`
|
||||
authUser = `where public_id in ('u_anon', 'u_auth', $1)`
|
||||
grantsQuery = `
|
||||
with
|
||||
users (id) as (
|
||||
select public_id
|
||||
from iam_user
|
||||
%s -- anonUser || authUser
|
||||
),
|
||||
user_groups (id) as (
|
||||
select group_id
|
||||
from iam_group_member_user,
|
||||
users
|
||||
where member_id in (users.id)
|
||||
),
|
||||
group_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_group_role,
|
||||
user_groups
|
||||
where principal_id in (user_groups.id)
|
||||
),
|
||||
user_roles (role_id) as (
|
||||
select role_id
|
||||
from iam_user_role,
|
||||
users
|
||||
where principal_id in (users.id)
|
||||
),
|
||||
user_group_roles (role_id) as (
|
||||
select role_id
|
||||
from group_roles
|
||||
union
|
||||
select role_id
|
||||
from user_roles
|
||||
),
|
||||
roles (role_id, grant_scope_id) as (
|
||||
select iam_role.public_id,
|
||||
iam_role.grant_scope_id
|
||||
from iam_role,
|
||||
user_group_roles
|
||||
where public_id in (user_group_roles.role_id)
|
||||
),
|
||||
final (role_scope, role_grant) as (
|
||||
select roles.grant_scope_id,
|
||||
iam_role_grant.canonical_grant
|
||||
from roles
|
||||
inner
|
||||
join iam_role_grant
|
||||
on roles.role_id = iam_role_grant.role_id
|
||||
)
|
||||
select role_scope as scope_id, role_grant as grant from final;
|
||||
`
|
||||
)
|
||||
|
||||
var query string
|
||||
switch userId {
|
||||
case "u_anon":
|
||||
query = fmt.Sprintf(grantsQuery, anonUser)
|
||||
default:
|
||||
query = fmt.Sprintf(grantsQuery, authUser)
|
||||
}
|
||||
|
||||
var grants []perms.GrantPair
|
||||
tx, err := r.reader.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows, err := tx.Query(query, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var g perms.GrantPair
|
||||
if err := r.reader.ScanRows(rows, &g); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grants = append(grants, g)
|
||||
}
|
||||
return grants, nil
|
||||
}
|
||||
@@ -184,7 +184,7 @@ func TestRepository_ListRoleGrants(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
require.NoError(conn.Where("1=1").Delete(allocRole()).Error)
|
||||
require.NoError(conn.Where("public_id != ?", "r_default").Delete(allocRole()).Error)
|
||||
role := TestRole(t, conn, tt.createScopeId)
|
||||
roleGrants := make([]string, 0, tt.createCnt)
|
||||
for i := 0; i < tt.createCnt; i++ {
|
||||
|
||||
@@ -30,7 +30,7 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, opt ...Option) (
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
var publicId string
|
||||
t := scope.StringToScopeType(s.Type)
|
||||
t := scope.Map[s.Type]
|
||||
if opts.withPublicId != "" {
|
||||
if !strings.HasPrefix(opts.withPublicId, t.Prefix()+"_") {
|
||||
return nil, fmt.Errorf("create scope: passed-in public ID %q has wrong prefix for type %q which uses prefix %q", opts.withPublicId, t.String(), t.Prefix())
|
||||
|
||||
@@ -12,6 +12,13 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/types/scope"
|
||||
)
|
||||
|
||||
// GrantPair is simply a struct that can be reference from other code to return
|
||||
// a set of scopes and grants to parse
|
||||
type GrantPair struct {
|
||||
ScopeId string
|
||||
Grant string
|
||||
}
|
||||
|
||||
// Scope provides an in-memory representation of iam.Scope without the
|
||||
// underlying storage references or capabilities.
|
||||
type Scope struct {
|
||||
@@ -123,7 +130,10 @@ func (g *Grant) unmarshalJSON(data []byte) error {
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to interpret %q as string", "type")
|
||||
}
|
||||
g.typ = resource.StringToResourceType(typ)
|
||||
g.typ = resource.Map[typ]
|
||||
if g.typ == resource.Unknown {
|
||||
return fmt.Errorf("unknown type specifier %q", typ)
|
||||
}
|
||||
}
|
||||
if rawActions, ok := raw["actions"]; ok {
|
||||
interfaceActions, ok := rawActions.([]interface{})
|
||||
@@ -169,7 +179,7 @@ func (g *Grant) unmarshalText(grantString string) error {
|
||||
|
||||
case "type":
|
||||
typeString := strings.ToLower(kv[1])
|
||||
g.typ = resource.StringToResourceType(typeString)
|
||||
g.typ = resource.Map[typeString]
|
||||
if g.typ == resource.Unknown {
|
||||
return fmt.Errorf("unknown type specifier %q", typeString)
|
||||
}
|
||||
@@ -273,6 +283,7 @@ func (g Grant) validateType() error {
|
||||
resource.HostCatalog,
|
||||
resource.HostSet,
|
||||
resource.Host,
|
||||
resource.Org,
|
||||
resource.Target:
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,26 @@ option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/wrappers.proto";
|
||||
|
||||
message Principal {
|
||||
// The ID of the principal.
|
||||
// Output only.
|
||||
string id = 1;
|
||||
|
||||
// The type of the principal.
|
||||
// Output only.
|
||||
string type = 2;
|
||||
|
||||
// The scope ID of the principal.
|
||||
// Output only.
|
||||
string scope_id = 3 [json_name="scope_id"];
|
||||
}
|
||||
|
||||
message Grant {
|
||||
// The user-supplied string.
|
||||
// Output only.
|
||||
|
||||
}
|
||||
|
||||
// Role contains all fields related to a Role resource
|
||||
message Role {
|
||||
// The ID of the Role
|
||||
@@ -42,13 +62,15 @@ message Role {
|
||||
// Output only.
|
||||
uint32 version = 8;
|
||||
|
||||
// The principals that are assigned this role.
|
||||
// The IDs (only) of principals that are assigned to this role.
|
||||
// Output only.
|
||||
repeated string user_ids = 9;
|
||||
// Output only.
|
||||
repeated string group_ids = 10;
|
||||
repeated string principal_ids = 9 [json_name="principal_ids"];
|
||||
|
||||
// The grants that this role provides for it's principals.
|
||||
// The principals that are assigned to this role.
|
||||
// Output only.
|
||||
repeated Principal principals = 10;
|
||||
|
||||
// The grants that this role provides for its principals.
|
||||
// Output only.
|
||||
repeated string grants = 11;
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package controller.api.services.v1;
|
||||
|
||||
option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api/services;services";
|
||||
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "controller/api/resources/authtokens/v1/authtoken.proto";
|
||||
|
||||
service AuthenticationService {
|
||||
// Authenticate validates credentials provided and returns an auth token.
|
||||
rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/orgs/{org_id}/auth-methods/{auth_method_id}:authenticate"
|
||||
body: "*"
|
||||
response_body: "item"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
|
||||
summary: "Authenticate a user to an Org and retrieve an authentication token."
|
||||
};
|
||||
}
|
||||
|
||||
// Logout terminates a user's current session.
|
||||
rpc Deauthenticate(DeauthenticateRequest) returns (DeauthenticateResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/orgs/{org_id}:deauthenticate"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
|
||||
summary: "Deauthenticate an authentication token from an Org."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// The layout of the struct for "credentials" field in AuthenticateRequest. This message isn't
|
||||
// directly referenced anywhere but is used here to define the expected field names and types.
|
||||
message PasswordCredentials {
|
||||
string name = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message AuthenticateRequest {
|
||||
string org_id = 1;
|
||||
// The id to the authmethod in the system being used for authentication. The auth method must be in the org
|
||||
// being logged in to.
|
||||
string auth_method_id = 2;
|
||||
// This can be "cookie" or "token". If not provided, "token" will be used. For now only type "token" is returned.
|
||||
string token_type = 3;
|
||||
|
||||
// credentials are the different possible credential names depending on what type of auth method is used.
|
||||
// For password auth method: should include only "name" and "password".
|
||||
google.protobuf.Struct credentials = 8;
|
||||
}
|
||||
|
||||
message AuthenticateResponse {
|
||||
resources.authtokens.v1.AuthToken item = 1;
|
||||
}
|
||||
|
||||
message DeauthenticateRequest {
|
||||
string org_id = 1;
|
||||
}
|
||||
message DeauthenticateResponse {}
|
||||
@@ -7,7 +7,6 @@ option go_package = "github.com/hashicorp/watchtower/internal/gen/controller/api
|
||||
import "protoc-gen-swagger/options/annotations.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "controller/api/resources/scopes/v1/org.proto";
|
||||
import "controller/api/resources/authtokens/v1/authtoken.proto";
|
||||
|
||||
service OrgService {
|
||||
|
||||
@@ -33,28 +32,6 @@ service OrgService {
|
||||
summary: "Lists all Orgs"
|
||||
};
|
||||
}
|
||||
|
||||
// Authenticate validates credentials provided and returns an auth token.
|
||||
rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/orgs/{org_id}:authenticate"
|
||||
body: "*"
|
||||
response_body: "item"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
|
||||
summary: "Authenticate a user to an Org and retrieve an authentication token."
|
||||
};
|
||||
}
|
||||
|
||||
// Logout terminates a user's current session.
|
||||
rpc Deauthenticate(DeauthenticateRequest) returns (DeauthenticateResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/orgs/{org_id}:deauthenticate"
|
||||
};
|
||||
option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = {
|
||||
summary: "Deauthenticate an authentication token from an Org."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message GetOrgRequest {
|
||||
@@ -73,28 +50,3 @@ message ListOrgsRequest {
|
||||
message ListOrgsResponse {
|
||||
repeated resources.scopes.v1.Org items = 1;
|
||||
}
|
||||
|
||||
message PasswordCredential {
|
||||
string login_name = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message AuthenticateRequest {
|
||||
string org_id = 1;
|
||||
// The id to the authmethod in the system being used for authentication. The auth method must be in the org
|
||||
// being logged in to.
|
||||
string auth_method_id = 2;
|
||||
// This can be "cookie" or "token". If not provided, "token" will be used. For now only type "token" is returned.
|
||||
string token_type = 3;
|
||||
|
||||
PasswordCredential password_credential = 4;
|
||||
}
|
||||
|
||||
message AuthenticateResponse {
|
||||
resources.authtokens.v1.AuthToken item = 1;
|
||||
}
|
||||
|
||||
message DeauthenticateRequest {
|
||||
string org_id = 1;
|
||||
}
|
||||
message DeauthenticateResponse {}
|
||||
@@ -296,8 +296,7 @@ message AddRolePrincipalsRequest {
|
||||
// The version ensures the role hasn't changed since it was last retrieved and if
|
||||
// it has the request will fail.
|
||||
google.protobuf.UInt32Value version = 4;
|
||||
repeated string user_ids = 5 [json_name="user_ids"];
|
||||
repeated string group_ids = 6 [json_name="group_ids"];
|
||||
repeated string principal_ids = 5 [json_name="principal_ids"];
|
||||
}
|
||||
|
||||
message AddRolePrincipalsResponse {
|
||||
@@ -311,8 +310,7 @@ message SetRolePrincipalsRequest {
|
||||
// The version ensures the role hasn't changed since it was last retrieved and if
|
||||
// it has the request will fail.
|
||||
google.protobuf.UInt32Value version = 4;
|
||||
repeated string user_ids = 5 [json_name="user_ids"];
|
||||
repeated string group_ids = 6 [json_name="group_ids"];
|
||||
repeated string principal_ids = 5 [json_name="principal_ids"];
|
||||
}
|
||||
|
||||
message SetRolePrincipalsResponse {
|
||||
@@ -326,8 +324,7 @@ message RemoveRolePrincipalsRequest {
|
||||
// The version ensures the role hasn't changed since it was last retrieved and if
|
||||
// it has the request will fail.
|
||||
google.protobuf.UInt32Value version = 4;
|
||||
repeated string user_ids = 5 [json_name="user_ids"];
|
||||
repeated string group_ids = 6 [json_name="group_ids"];
|
||||
repeated string principal_ids = 5 [json_name="principal_ids"];
|
||||
}
|
||||
|
||||
message RemoveRolePrincipalsResponse {
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/config"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
// The base Server object, containing things shared between Controllers and
|
||||
// Workers
|
||||
*base.Server
|
||||
RawConfig *config.Config
|
||||
BaseContext context.Context
|
||||
// The underlying configuration, passed in here to avoid duplicating values
|
||||
// everywhere
|
||||
RawConfig *config.Config
|
||||
// If set, authorization checking occurrs but failures are ignored
|
||||
DisableAuthorizationFailures bool
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/cmd/config"
|
||||
)
|
||||
@@ -65,8 +66,9 @@ func TestHandler_CORS(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tc := NewTestController(t, &TestControllerOpts{
|
||||
Config: cfg,
|
||||
DefaultOrgId: "o_1234567890",
|
||||
Config: cfg,
|
||||
DefaultOrgId: "o_1234567890",
|
||||
DisableAuthorizationFailures: true,
|
||||
})
|
||||
defer tc.Shutdown()
|
||||
|
||||
@@ -161,12 +163,13 @@ func TestHandler_CORS(t *testing.T) {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
// Create a client with the right address
|
||||
client := tc.Client()
|
||||
client.SetAddr(tc.ApiAddrs()[c.listenerNum-1])
|
||||
err := client.SetAddr(tc.ApiAddrs()[c.listenerNum-1])
|
||||
require.NoError(t, err)
|
||||
client.SetOrg("o_1234567890")
|
||||
|
||||
// Create the request
|
||||
req, err := client.NewRequest(tc.Context(), c.method, "projects", nil)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Append headers
|
||||
if c.origin != "" {
|
||||
@@ -178,7 +181,7 @@ func TestHandler_CORS(t *testing.T) {
|
||||
|
||||
// Run the request, do basic checks
|
||||
resp, err := client.Do(req)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, c.code, resp.HttpResponse().StatusCode)
|
||||
|
||||
// If options and we expect it to be successful, run some checks
|
||||
|
||||
@@ -3,9 +3,10 @@ package controller
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -15,7 +16,9 @@ import (
|
||||
"github.com/hashicorp/watchtower/api"
|
||||
"github.com/hashicorp/watchtower/globals"
|
||||
"github.com/hashicorp/watchtower/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/watchtower/internal/perms"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/authenticate"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/groups"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/host_catalogs"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/host_sets"
|
||||
@@ -24,6 +27,10 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/projects"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/roles"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/users"
|
||||
"github.com/hashicorp/watchtower/internal/types/action"
|
||||
"github.com/hashicorp/watchtower/internal/types/resource"
|
||||
"github.com/hashicorp/watchtower/internal/types/scope"
|
||||
"github.com/kr/pretty"
|
||||
)
|
||||
|
||||
type HandlerProperties struct {
|
||||
@@ -54,8 +61,7 @@ func handleGrpcGateway(c *Controller) (http.Handler, error) {
|
||||
// Register*ServiceHandlerServer methods ignore the passed in ctx. Using the baseContext now just in case this changes
|
||||
// in the future, at which point we'll want to be using the baseContext.
|
||||
ctx := c.baseContext
|
||||
mux := runtime.NewServeMux(runtime.WithMetadata(handlers.TokenAuthenticator(c.logger, c.AuthTokenRepoFn)),
|
||||
runtime.WithProtoErrorHandler(handlers.ErrorHandler(c.logger)))
|
||||
mux := runtime.NewServeMux(runtime.WithProtoErrorHandler(handlers.ErrorHandler(c.logger)))
|
||||
hcs, err := host_catalogs.NewService(c.StaticHostRepoFn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create host catalog handler service: %w", err)
|
||||
@@ -69,6 +75,13 @@ func handleGrpcGateway(c *Controller) (http.Handler, error) {
|
||||
if err := services.RegisterHostServiceHandlerServer(ctx, mux, &hosts.Service{}); err != nil {
|
||||
return nil, fmt.Errorf("failed to register host service handler: %w", err)
|
||||
}
|
||||
auths, err := authenticate.NewService(c.IamRepoFn, c.AuthTokenRepoFn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create authentication handler service: %w", err)
|
||||
}
|
||||
if err := services.RegisterAuthenticationServiceHandlerServer(ctx, mux, auths); err != nil {
|
||||
return nil, fmt.Errorf("failed to register authenticate service handler: %w", err)
|
||||
}
|
||||
os, err := orgs.NewService(c.IamRepoFn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create org handler service: %w", err)
|
||||
@@ -121,27 +134,76 @@ func wrapHandlerWithCommonFuncs(h http.Handler, c *Controller, props HandlerProp
|
||||
if maxRequestSize == 0 {
|
||||
maxRequestSize = globals.DefaultMaxRequestSize
|
||||
}
|
||||
var defaultOrgId string
|
||||
if c != nil && c.conf != nil {
|
||||
defaultOrgId = c.conf.DefaultOrgId
|
||||
|
||||
logUrls := os.Getenv("WATCHTOWER_LOG_URLS") != ""
|
||||
|
||||
disableAuthzFailures := c.conf.DisableAuthorizationFailures ||
|
||||
(c.conf.RawConfig.DevController && os.Getenv("WATCHTOWER_DEV_SKIP_AUTHZ") != "")
|
||||
if disableAuthzFailures {
|
||||
c.logger.Warn("AUTHORIZATION CHECKING DISABLED")
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if defaultOrgId != "" {
|
||||
splitPath := strings.Split(r.URL.Path, "/")
|
||||
if len(splitPath) >= 3 && splitPath[2] == "projects" {
|
||||
http.Redirect(w, r, path.Join("/v1/orgs", defaultOrgId, strings.Join(splitPath[2:], "/")), 307)
|
||||
return
|
||||
}
|
||||
if logUrls {
|
||||
c.logger.Trace("request received", "url", r.URL.String())
|
||||
}
|
||||
|
||||
// Set the Cache-Control header for all responses returned
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
|
||||
// Start with the request context
|
||||
ctx := r.Context()
|
||||
var cancelFunc context.CancelFunc
|
||||
// Add our timeout
|
||||
ctx, cancelFunc = context.WithTimeout(ctx, maxRequestDuration)
|
||||
// Start with the request context and our timeout
|
||||
ctx, cancelFunc := context.WithTimeout(r.Context(), maxRequestDuration)
|
||||
defer cancelFunc()
|
||||
|
||||
userId := "u_anon"
|
||||
var res *perms.Resource
|
||||
var act action.Type
|
||||
var err error
|
||||
var authzResults *perms.ACLResults
|
||||
|
||||
if r.Method == http.MethodOptions {
|
||||
// Don't perform authorization checking for preflight requests, at
|
||||
// least for now. We could add it later if we wanted as an action on
|
||||
// global or something but likely it would just be enabled/disabled
|
||||
// per listener instead.
|
||||
goto AUTHZ_FINISHED
|
||||
}
|
||||
|
||||
// Perform authz checking
|
||||
res, act, err = decorateAuthParams(r)
|
||||
if err != nil {
|
||||
c.logger.Trace("error reading auth parameters from URL", "url", r.URL.Path, "error", err)
|
||||
// Maybe this isn't the best option, but a URL we can't parse from
|
||||
// an auth perspective is probably just an invalid URL altogether.
|
||||
// Treating it as a bad request can be perceived to be less leaky
|
||||
// than a 404.
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// The resource is only nil with no error if the path is something
|
||||
// unauthenticated, e.g. the UI serving path.
|
||||
if res != nil {
|
||||
authzResults, userId, err = c.performAuthzCheck(ctx, r, res, act)
|
||||
if err != nil {
|
||||
c.logger.Error("error during authz check", "error", err)
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if userId == "" || !authzResults.Allowed {
|
||||
// TODO: Decide whether to remove this
|
||||
if disableAuthzFailures {
|
||||
c.logger.Info("failed authz info for request", "resource", pretty.Sprint(res), "user_id", userId, "action", act.String())
|
||||
} else {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AUTHZ_FINISHED:
|
||||
// Add the user ID to the context
|
||||
ctx = context.WithValue(ctx, globals.ContextUserIdValue, userId)
|
||||
// Add a size limiter if desired
|
||||
if maxRequestSize > 0 {
|
||||
ctx = context.WithValue(ctx, "max_request_size", maxRequestSize)
|
||||
@@ -150,8 +212,6 @@ func wrapHandlerWithCommonFuncs(h http.Handler, c *Controller, props HandlerProp
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
h.ServeHTTP(w, r)
|
||||
cancelFunc()
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
@@ -203,8 +263,8 @@ func wrapHandlerWithCors(h http.Handler, props HandlerProperties) http.Handler {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
|
||||
err := &api.Error{
|
||||
Status: api.Int(http.StatusForbidden),
|
||||
Code: api.String("origin forbidden"),
|
||||
Status: http.StatusForbidden,
|
||||
Code: "origin forbidden",
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
@@ -231,10 +291,277 @@ func wrapHandlerWithCors(h http.Handler, props HandlerProperties) http.Handler {
|
||||
}
|
||||
|
||||
h.ServeHTTP(w, req)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func decorateAuthParams(r *http.Request) (*perms.Resource, action.Type, error) {
|
||||
if r == nil {
|
||||
return nil, action.Unknown, errors.New("decorate auth params: incoming request is nil")
|
||||
}
|
||||
|
||||
// Remove trailing and leading slashes
|
||||
trimmedPath := strings.Trim(r.URL.Path, "/")
|
||||
if !strings.HasPrefix(trimmedPath, "v1") {
|
||||
// Don't look for auth params for requests to fetch the UI
|
||||
return nil, action.Unknown, nil
|
||||
}
|
||||
splitPath := strings.Split(strings.TrimPrefix(trimmedPath, "v1"), "/")
|
||||
splitLen := len(splitPath)
|
||||
if splitLen == 0 {
|
||||
return nil, action.Unknown, fmt.Errorf("decorate auth params: invalid path")
|
||||
}
|
||||
|
||||
var act action.Type
|
||||
var typStr string
|
||||
scp := scope.Global
|
||||
res := &perms.Resource{
|
||||
ScopeId: scope.Global.String(),
|
||||
}
|
||||
|
||||
// Handle non-custom types. We'll deal with custom types, including list,
|
||||
// after parsing the path.
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
act = action.Read
|
||||
case "POST":
|
||||
act = action.Create
|
||||
case "PATCH":
|
||||
act = action.Update
|
||||
case "DELETE":
|
||||
act = action.Delete
|
||||
default:
|
||||
return nil, action.Unknown, fmt.Errorf("decorate auth params: unknown method %q", r.Method)
|
||||
}
|
||||
|
||||
// Look for a custom action
|
||||
colonSplit := strings.Split(splitPath[splitLen-1], ":")
|
||||
switch len(colonSplit) {
|
||||
case 1:
|
||||
// No custom action specified
|
||||
case 2:
|
||||
actStr := colonSplit[len(colonSplit)-1]
|
||||
act = action.Map[actStr]
|
||||
if act == action.Unknown || act == action.All {
|
||||
return nil, action.Unknown, fmt.Errorf("decorate auth params: unknown action %q", actStr)
|
||||
}
|
||||
// Keep going with the logic without the custom action
|
||||
splitPath[splitLen-1] = colonSplit[0]
|
||||
default:
|
||||
return nil, action.Unknown, fmt.Errorf("decorate auth params: unexpected number of colons in last segment %q", colonSplit[len(colonSplit)-1])
|
||||
}
|
||||
|
||||
// Walk backwards. As we walk backwards we look for scopes and figure out if
|
||||
// we're operating on a resource or a collection. We also populate the pin.
|
||||
// The rules for the pin are as follows:
|
||||
//
|
||||
// * If the last segment is a collection, the pin is the immediately
|
||||
// preceding ID
|
||||
//
|
||||
// * If the last segment is an ID, the pin is the immediately preceding ID
|
||||
// not including the last segment
|
||||
//
|
||||
// * If at the end of the logic the pin is the id of a scope ("global",
|
||||
// "o_...", "p_...") then there is no pin. The scopes are already enclosing
|
||||
// so a pin is redundant.
|
||||
nextIdIsPin := true
|
||||
for i := splitLen - 1; i >= 0; i-- {
|
||||
segment := splitPath[i]
|
||||
|
||||
// Collections don't contain underscores; every resource ID does.
|
||||
segmentIsCollection := !strings.Contains(segment, "_")
|
||||
|
||||
if !segmentIsCollection && i != splitLen-1 && nextIdIsPin {
|
||||
res.Pin = segment
|
||||
nextIdIsPin = false
|
||||
}
|
||||
|
||||
// Update the scope. Set it to org only if it's at global (that way we
|
||||
// don't override project with org). We have to check if it's one less
|
||||
// than the length of the split because operating on the id of a scope
|
||||
// is actually in the enclosing scope (since you're in the parent scope
|
||||
// operating on a child scope).
|
||||
switch segment {
|
||||
case "projects":
|
||||
if i < splitLen-2 {
|
||||
scp = scope.Project
|
||||
res.ScopeId = splitPath[i+1]
|
||||
}
|
||||
case "orgs":
|
||||
if scp == scope.Global {
|
||||
if i < splitLen-2 {
|
||||
scp = scope.Org
|
||||
res.ScopeId = splitPath[i+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if segment == "" {
|
||||
// This could be the case if we have an action like
|
||||
// /orgs/o_1234/projects/p_1234/:set-defaults to act on the project
|
||||
// itself but within its own scope
|
||||
continue
|
||||
}
|
||||
|
||||
if typStr == "" {
|
||||
// The resource check takes place inside the type check because if
|
||||
// we've identified the type we have either already identified the
|
||||
// right-most resource ID or we're operating on a collection, so
|
||||
// this prevents us from finding a different ID earlier in the path.
|
||||
//
|
||||
// We continue on with the enclosing loop anyways though to ensure
|
||||
// we find the right scope.
|
||||
if res.Id == "" && !segmentIsCollection {
|
||||
res.Id = segment
|
||||
} else {
|
||||
// Every collection is the plural of the resource type so drop
|
||||
// the last 's'
|
||||
if !strings.HasSuffix(segment, "s") {
|
||||
return nil, action.Unknown, fmt.Errorf("decorate auth params: invalid collection syntax for %q", segment)
|
||||
}
|
||||
typStr = strings.TrimSuffix(segment, "s")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if typStr != "" {
|
||||
res.Type = resource.Map[typStr]
|
||||
if res.Type == resource.Unknown {
|
||||
return nil, action.Unknown, fmt.Errorf("decorate auth params: unknown resource type %q", typStr)
|
||||
}
|
||||
} else if res.Id == "" {
|
||||
return nil, action.Unknown, errors.New("decorate auth params: id and type both not found")
|
||||
}
|
||||
|
||||
// If we're operating on a collection (that is, the ID is blank) and it's a
|
||||
// GET, it's actually a list
|
||||
if res.Id == "" && act == action.Read {
|
||||
act = action.List
|
||||
}
|
||||
|
||||
// If the pin ended up being a scope, nil it out
|
||||
if res.Pin != "" {
|
||||
if res.Pin == "global" ||
|
||||
strings.HasPrefix(res.Pin, "o_") ||
|
||||
strings.HasPrefix(res.Pin, "p_") {
|
||||
res.Pin = ""
|
||||
}
|
||||
}
|
||||
|
||||
return res, act, nil
|
||||
}
|
||||
|
||||
type tokenFormat int
|
||||
|
||||
const (
|
||||
authTokenTypeUnknown tokenFormat = iota
|
||||
authTokenTypeBearer
|
||||
authTokenTypeSplitCookie
|
||||
)
|
||||
|
||||
const (
|
||||
headerAuthMethod = "Authorization"
|
||||
httpOnlyCookieName = "wt-http-token-cookie"
|
||||
jsVisibleCookieName = "wt-js-token-cookie"
|
||||
)
|
||||
|
||||
func (c *Controller) performAuthzCheck(ctx context.Context, req *http.Request, res *perms.Resource, act action.Type) (*perms.ACLResults, string, error) {
|
||||
userId := "u_anon"
|
||||
|
||||
if res == nil {
|
||||
return nil, userId, errors.New("perform authz check: res is nil")
|
||||
}
|
||||
var receivedTokenType tokenFormat
|
||||
var fullToken, token, publicId string
|
||||
|
||||
// First, get the token, either from the authorization header or from split
|
||||
// cookies
|
||||
{
|
||||
if authHeader := req.Header.Get("Authorization"); authHeader != "" {
|
||||
headerSplit := strings.SplitN(strings.TrimSpace(authHeader), " ", 2)
|
||||
if len(headerSplit) == 2 && strings.EqualFold(strings.TrimSpace(headerSplit[0]), "bearer") {
|
||||
receivedTokenType = authTokenTypeBearer
|
||||
fullToken = strings.TrimSpace(headerSplit[1])
|
||||
}
|
||||
}
|
||||
if receivedTokenType != authTokenTypeBearer {
|
||||
var httpCookiePayload string
|
||||
var jsCookiePayload string
|
||||
if hc, err := req.Cookie(httpOnlyCookieName); err == nil {
|
||||
httpCookiePayload = hc.Value
|
||||
}
|
||||
if jc, err := req.Cookie(jsVisibleCookieName); err == nil {
|
||||
jsCookiePayload = jc.Value
|
||||
}
|
||||
if httpCookiePayload != "" && jsCookiePayload != "" {
|
||||
receivedTokenType = authTokenTypeSplitCookie
|
||||
fullToken = jsCookiePayload + httpCookiePayload
|
||||
}
|
||||
}
|
||||
|
||||
if receivedTokenType == authTokenTypeUnknown || fullToken == "" {
|
||||
// We didn't find auth info or a client screwed up and put in a
|
||||
// blank header instead of nothing at all, so carry on as the
|
||||
// anonymous user
|
||||
goto GRANTSLOOKUP
|
||||
}
|
||||
|
||||
splitFullToken := strings.Split(fullToken, "_")
|
||||
if len(splitFullToken) != 3 {
|
||||
return nil, userId, fmt.Errorf("perform authz check: unexpected number of segments in token, expected %d, found %d", 3, len(splitFullToken))
|
||||
}
|
||||
|
||||
token = splitFullToken[2]
|
||||
publicId = strings.Join(splitFullToken[0:2], "_")
|
||||
|
||||
if receivedTokenType == authTokenTypeUnknown || token == "" || publicId == "" {
|
||||
return nil, userId, fmt.Errorf("perform authz check: after parsing, could not find valid token")
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the token and fetch the corresponding user ID
|
||||
{
|
||||
tokenRepo, err := c.AuthTokenRepoFn()
|
||||
if err != nil {
|
||||
return nil, userId, fmt.Errorf("perform authz check: failed to get authtoken repo: %w", err)
|
||||
}
|
||||
|
||||
at, err := tokenRepo.ValidateToken(ctx, publicId, token)
|
||||
if err != nil {
|
||||
return nil, userId, fmt.Errorf("perform authz check: failed to validate token: %w", err)
|
||||
}
|
||||
if at != nil {
|
||||
userId = at.GetIamUserId()
|
||||
}
|
||||
}
|
||||
|
||||
GRANTSLOOKUP:
|
||||
var parsedGrants []perms.Grant
|
||||
var grantPairs []perms.GrantPair
|
||||
// Fetch and parse grants for this user ID
|
||||
{
|
||||
iamRepo, err := c.IamRepoFn()
|
||||
if err != nil {
|
||||
return nil, userId, fmt.Errorf("perform authz check: failed to get iam repo: %w", err)
|
||||
}
|
||||
grantPairs, err = iamRepo.GrantsForUser(ctx, userId)
|
||||
if err != nil {
|
||||
return nil, userId, fmt.Errorf("perform authz check: failed to query for user grants: %w", err)
|
||||
}
|
||||
parsedGrants = make([]perms.Grant, 0, len(grantPairs))
|
||||
for _, pair := range grantPairs {
|
||||
parsed, err := perms.Parse(pair.ScopeId, userId, pair.Grant)
|
||||
if err != nil {
|
||||
return nil, userId, fmt.Errorf("perform authz check: failed to parse grant %#v: %w", pair.Grant, err)
|
||||
}
|
||||
parsedGrants = append(parsedGrants, parsed)
|
||||
}
|
||||
}
|
||||
|
||||
acl := perms.NewACL(parsedGrants...)
|
||||
allowed := acl.Allowed(*res, act)
|
||||
return &allowed, userId, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func WrapForwardedForHandler(h http.Handler, authorizedAddrs []*sockaddr.SockAddrMarshaler, rejectNotPresent, rejectNonAuthz bool, hopSkips int) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -2,13 +2,18 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/hashicorp/watchtower/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/watchtower/internal/types/action"
|
||||
"github.com/hashicorp/watchtower/internal/types/resource"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -119,6 +124,28 @@ func TestGrpcGatewayRouting(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthenticationHandler(t *testing.T) {
|
||||
c := NewTestController(t, &TestControllerOpts{DefaultOrgId: "o_1234567890"})
|
||||
defer c.Shutdown()
|
||||
|
||||
resp, err := http.Post(fmt.Sprintf("%s/v1/orgs/o_1234567890/auth-methods/am_1234567890:authenticate", c.ApiAddrs()[0]), "application/json",
|
||||
strings.NewReader(`{"token_type": null, "credentials": {"name":"test", "password": "test"}}`))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode, "Got response: %v", resp)
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
body := make(map[string]interface{})
|
||||
require.NoError(t, json.Unmarshal(b, &body))
|
||||
|
||||
require.Contains(t, body, "id")
|
||||
require.Contains(t, body, "token")
|
||||
pubId, tok := body["id"].(string), body["token"].(string)
|
||||
assert.NotEmpty(t, pubId)
|
||||
assert.NotEmpty(t, tok)
|
||||
assert.Truef(t, strings.HasPrefix(tok, pubId), "Token: %q, Id: %q", tok, pubId)
|
||||
}
|
||||
|
||||
func TestGrpcGatewayRouting_CustomActions(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
// The unimplemented result indicates the grpc routing is happening successfully otherwise it would return NotFound.
|
||||
@@ -167,7 +194,9 @@ func TestGrpcGatewayRouting_CustomActions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHandleGrpcGateway(t *testing.T) {
|
||||
c := NewTestController(t, nil)
|
||||
c := NewTestController(t, &TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
})
|
||||
defer c.Shutdown()
|
||||
|
||||
cases := []struct {
|
||||
@@ -177,12 +206,12 @@ func TestHandleGrpcGateway(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
"Non existent path",
|
||||
"v1/this-is-made-up",
|
||||
http.StatusNotFound,
|
||||
"v1/this-is-made-ups",
|
||||
http.StatusBadRequest,
|
||||
},
|
||||
{
|
||||
"Unimplemented path",
|
||||
"v1/orgs/1/projects/2/host-catalogs/3/host-sets/4",
|
||||
"v1/orgs/1/projects/2/host-catalogs/3/host-sets/hs_4",
|
||||
http.StatusMethodNotAllowed,
|
||||
},
|
||||
}
|
||||
@@ -200,3 +229,221 @@ func TestHandleGrpcGateway(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_AuthDecoration(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
path string
|
||||
method string
|
||||
action action.Type
|
||||
scope string
|
||||
resource resource.Type
|
||||
id string
|
||||
pin string
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "global scope, read, with id",
|
||||
path: "/v1/users/u_anon",
|
||||
method: "GET",
|
||||
action: action.Read,
|
||||
scope: "global",
|
||||
resource: resource.User,
|
||||
id: "u_anon",
|
||||
},
|
||||
{
|
||||
name: "global scope, update, with id",
|
||||
path: "/v1/auth-methods/am_1234",
|
||||
method: "PATCH",
|
||||
action: action.Update,
|
||||
scope: "global",
|
||||
resource: resource.AuthMethod,
|
||||
id: "am_1234",
|
||||
},
|
||||
{
|
||||
name: "global scope, delete",
|
||||
path: "/v1/orgs/o_1234",
|
||||
method: "DELETE",
|
||||
action: action.Delete,
|
||||
scope: "global",
|
||||
resource: resource.Org,
|
||||
id: "o_1234",
|
||||
},
|
||||
{
|
||||
name: "global scope, create",
|
||||
path: "/v1/roles",
|
||||
method: "POST",
|
||||
action: action.Create,
|
||||
scope: "global",
|
||||
resource: resource.Role,
|
||||
},
|
||||
{
|
||||
name: "global, invalid collection syntax",
|
||||
path: "/v1/org",
|
||||
wantErrContains: "invalid collection syntax",
|
||||
},
|
||||
{
|
||||
name: "global, custom action",
|
||||
path: "/v1/orgs/o_123/auth-methods/am_1234:authenticate",
|
||||
method: "POST",
|
||||
action: action.Authenticate,
|
||||
scope: "o_123",
|
||||
resource: resource.AuthMethod,
|
||||
id: "am_1234",
|
||||
},
|
||||
{
|
||||
name: "root, unknown action",
|
||||
path: "/v1/:authentifake",
|
||||
wantErrContains: "unknown action",
|
||||
},
|
||||
{
|
||||
name: "root, unknown empty action",
|
||||
path: "/v1/:",
|
||||
wantErrContains: "unknown action",
|
||||
},
|
||||
{
|
||||
name: "root, invalid method",
|
||||
path: "/v1/:authenticate",
|
||||
method: "FOOBAR",
|
||||
wantErrContains: "unknown method",
|
||||
},
|
||||
{
|
||||
name: "root, wrong number of colons",
|
||||
path: "/v1/:auth:enticate",
|
||||
wantErrContains: "unexpected number of colons",
|
||||
},
|
||||
{
|
||||
name: "org scope, valid",
|
||||
path: "/v1/orgs/o_abc123/auth-methods",
|
||||
method: "POST",
|
||||
action: action.Create,
|
||||
scope: "o_abc123",
|
||||
resource: resource.AuthMethod,
|
||||
},
|
||||
{
|
||||
name: "project scope, valid",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234/host-catalogs",
|
||||
method: "POST",
|
||||
action: action.Create,
|
||||
scope: "p_1234",
|
||||
resource: resource.HostCatalog,
|
||||
},
|
||||
{
|
||||
name: "project scope, action on project",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234/:set-principals",
|
||||
method: "POST",
|
||||
action: action.SetPrincipals,
|
||||
scope: "p_1234",
|
||||
resource: resource.Project,
|
||||
id: "p_1234",
|
||||
},
|
||||
{
|
||||
name: "org scope, action on project",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234:set-principals",
|
||||
method: "POST",
|
||||
action: action.SetPrincipals,
|
||||
scope: "o_abc123",
|
||||
resource: resource.Project,
|
||||
id: "p_1234",
|
||||
},
|
||||
{
|
||||
name: "org scope, get on collection is list",
|
||||
path: "/v1/orgs/o_abc123/projects",
|
||||
action: action.List,
|
||||
scope: "o_abc123",
|
||||
resource: resource.Project,
|
||||
},
|
||||
{
|
||||
name: "org scope, action on org",
|
||||
path: "/v1/orgs/o_abc123/:deauthenticate",
|
||||
action: action.Deauthenticate,
|
||||
scope: "o_abc123",
|
||||
resource: resource.Org,
|
||||
id: "o_abc123",
|
||||
},
|
||||
{
|
||||
name: "top level action, invalid",
|
||||
path: "/v1/:read",
|
||||
wantErrContains: "id and type both not found",
|
||||
},
|
||||
{
|
||||
name: "top level, invalid",
|
||||
path: "/v1/",
|
||||
wantErrContains: "id and type both not found",
|
||||
},
|
||||
{
|
||||
name: "non-api path",
|
||||
path: "/",
|
||||
},
|
||||
{
|
||||
name: "project scope, pinning collection",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234/host-catalogs/hc_1234/host-sets",
|
||||
action: action.List,
|
||||
scope: "p_1234",
|
||||
pin: "hc_1234",
|
||||
resource: resource.HostSet,
|
||||
},
|
||||
{
|
||||
name: "project scope, pinning collection, custom action",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234/host-catalogs/hc_1234/host-sets:create",
|
||||
action: action.Create,
|
||||
scope: "p_1234",
|
||||
pin: "hc_1234",
|
||||
resource: resource.HostSet,
|
||||
},
|
||||
{
|
||||
name: "project scope, pinning id",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234/host-catalogs/hc_1234/host-sets/hs_abc",
|
||||
action: action.Read,
|
||||
id: "hs_abc",
|
||||
scope: "p_1234",
|
||||
pin: "hc_1234",
|
||||
resource: resource.HostSet,
|
||||
},
|
||||
{
|
||||
name: "project scope, pinning id, custom action",
|
||||
path: "/v1/orgs/o_abc123/projects/p_1234/host-catalogs/hc_1234/host-sets/hs_abc:update",
|
||||
action: action.Update,
|
||||
id: "hs_abc",
|
||||
scope: "p_1234",
|
||||
pin: "hc_1234",
|
||||
resource: resource.HostSet,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
require, assert := require.New(t), assert.New(t)
|
||||
if tc.method == "" {
|
||||
tc.method = "GET"
|
||||
}
|
||||
req, err := http.NewRequest(tc.method, fmt.Sprintf("http://127.0.0.1:9200:%s", tc.path), nil)
|
||||
require.NoError(err)
|
||||
|
||||
res, act, err := decorateAuthParams(nil)
|
||||
assert.Nil(res)
|
||||
require.Error(err)
|
||||
assert.Equal(action.Unknown, act)
|
||||
assert.Contains(err.Error(), "incoming request is nil")
|
||||
|
||||
res, act, err = decorateAuthParams(req)
|
||||
if tc.wantErrContains != "" {
|
||||
require.Error(err)
|
||||
assert.Contains(err.Error(), tc.wantErrContains, err.Error())
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
|
||||
if tc.path == "/" {
|
||||
return
|
||||
}
|
||||
|
||||
require.NotNil(res)
|
||||
require.NotEqual(action.Unknown, act)
|
||||
assert.Equal(tc.scope, res.ScopeId, "scope")
|
||||
assert.Equal(tc.action, act, "action")
|
||||
assert.Equal(tc.resource, res.Type, "type")
|
||||
assert.Equal(tc.id, res.Id, "id")
|
||||
assert.Equal(tc.pin, res.Pin, "pin")
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package authenticate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base32"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/authtoken"
|
||||
"github.com/hashicorp/watchtower/internal/db"
|
||||
pba "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/authtokens"
|
||||
pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/watchtower/internal/iam"
|
||||
iamStore "github.com/hashicorp/watchtower/internal/iam/store"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/common"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers"
|
||||
"github.com/hashicorp/watchtower/internal/types/scope"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const orgIdFieldName = "org_id"
|
||||
|
||||
var (
|
||||
reInvalidID = regexp.MustCompile("[^A-Za-z0-9]")
|
||||
|
||||
// TODO: Remove once auth methods are in
|
||||
OrgScope string
|
||||
RWDb = new(atomic.Value)
|
||||
)
|
||||
|
||||
func init() {
|
||||
RWDb.Store((*db.Db)(nil))
|
||||
}
|
||||
|
||||
// Service handles request as described by the pbs.OrgServiceServer interface.
|
||||
type Service struct {
|
||||
iamRepo common.IamRepoFactory
|
||||
authTokenRepo common.AuthTokenRepoFactory
|
||||
}
|
||||
|
||||
// NewService returns an org service which handles org related requests to watchtower.
|
||||
func NewService(iamRepo common.IamRepoFactory, atRepo common.AuthTokenRepoFactory) (Service, error) {
|
||||
if iamRepo == nil {
|
||||
return Service{}, fmt.Errorf("nil iam repository provided")
|
||||
}
|
||||
if atRepo == nil {
|
||||
return Service{}, fmt.Errorf("nil auth token repository provided")
|
||||
}
|
||||
|
||||
return Service{iamRepo: iamRepo, authTokenRepo: atRepo}, nil
|
||||
}
|
||||
|
||||
var _ pbs.AuthenticationServiceServer = Service{}
|
||||
|
||||
// Authenticate implements the interface pbs.AuthenticationServiceServer.
|
||||
func (s Service) Authenticate(ctx context.Context, req *pbs.AuthenticateRequest) (*pbs.AuthenticateResponse, error) {
|
||||
if err := validateAuthenticateRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tok, err := s.authenticateWithRepo(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbs.AuthenticateResponse{Item: tok}, nil
|
||||
}
|
||||
|
||||
// Deauthenticate implements the interface pbs.AuthenticationServiceServer.
|
||||
func (s Service) Deauthenticate(ctx context.Context, req *pbs.DeauthenticateRequest) (*pbs.DeauthenticateResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Requested method is unimplemented for Org.")
|
||||
}
|
||||
|
||||
func (s Service) authenticateWithRepo(ctx context.Context, req *pbs.AuthenticateRequest) (*pba.AuthToken, error) {
|
||||
userRepo, err := s.iamRepo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
atRepo, err := s.authTokenRepo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Place holder for making a request to authenticate
|
||||
creds := req.GetCredentials().GetFields()
|
||||
pwName, password := creds["name"], creds["password"]
|
||||
if pwName.GetStringValue() == "wrong" && password.GetStringValue() == "wrong" {
|
||||
return nil, status.Error(codes.Unauthenticated, "Unable to authenticate.")
|
||||
}
|
||||
// Get back a password.Account with a CredentialId string and a public Id
|
||||
// Create a fake auth account ID for the moment
|
||||
acctIdBytes := sha256.Sum256([]byte(pwName.GetStringValue()))
|
||||
acctId := fmt.Sprintf("aa_%s", base32.StdEncoding.EncodeToString(acctIdBytes[:])[0:10])
|
||||
|
||||
aAcct := &iam.AuthAccount{AuthAccount: &iamStore.AuthAccount{
|
||||
PublicId: acctId,
|
||||
ScopeId: OrgScope,
|
||||
AuthMethodId: req.AuthMethodId,
|
||||
}}
|
||||
RWDb.Load().(*db.Db).Create(ctx, aAcct)
|
||||
|
||||
u, err := userRepo.LookupUserWithLogin(ctx, acctId, iam.WithAutoVivify(true))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tok, err := atRepo.CreateAuthToken(ctx, u.GetPublicId(), acctId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tok.Token = tok.GetPublicId() + "_" + tok.GetToken()
|
||||
return toProto(tok), nil
|
||||
}
|
||||
|
||||
func toProto(t *authtoken.AuthToken) *pba.AuthToken {
|
||||
return &pba.AuthToken{
|
||||
Id: t.GetPublicId(),
|
||||
Token: t.GetToken(),
|
||||
UserId: t.GetIamUserId(),
|
||||
AuthMethodId: t.GetAuthMethodId(),
|
||||
CreatedTime: t.GetCreateTime().GetTimestamp(),
|
||||
UpdatedTime: t.GetUpdateTime().GetTimestamp(),
|
||||
ApproximateLastUsedTime: t.GetApproximateLastAccessTime().GetTimestamp(),
|
||||
ExpirationTime: t.GetExpirationTime().GetTimestamp(),
|
||||
}
|
||||
}
|
||||
|
||||
// A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce
|
||||
// requirements on the structure of the request. They verify that:
|
||||
// * The path passed in is correctly formatted
|
||||
// * All required parameters are set
|
||||
// * There are no conflicting parameters provided
|
||||
func validateAuthenticateRequest(req *pbs.AuthenticateRequest) error {
|
||||
badFields := make(map[string]string)
|
||||
if !validId(req.GetOrgId(), scope.Org.Prefix()+"_") {
|
||||
badFields[orgIdFieldName] = "Invalid formatted identifier."
|
||||
}
|
||||
if strings.TrimSpace(req.GetAuthMethodId()) == "" {
|
||||
badFields["auth_method_id"] = "This is a required field."
|
||||
} else if validId(req.GetAuthMethodId(), "am") {
|
||||
badFields["auth_method_id"] = "Invalid formatted identifier."
|
||||
}
|
||||
// TODO: Update this when we enable different auth method types.
|
||||
if req.GetCredentials() == nil {
|
||||
badFields["credentials"] = "This is a required field."
|
||||
}
|
||||
// TODO: Update this when we enable split cookie token types.
|
||||
tType := strings.ToLower(strings.TrimSpace(req.GetTokenType()))
|
||||
if tType != "" && tType != "token" {
|
||||
badFields["token_type"] = "The only accepted type is 'token'."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Invalid fields provided in request.", badFields)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validId(id, prefix string) bool {
|
||||
if !strings.HasPrefix(id, prefix) {
|
||||
return false
|
||||
}
|
||||
id = strings.TrimPrefix(id, prefix)
|
||||
return !reInvalidID.Match([]byte(id))
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package authenticate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base32"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
structpb "github.com/golang/protobuf/ptypes/struct"
|
||||
"github.com/hashicorp/watchtower/internal/authtoken"
|
||||
"github.com/hashicorp/watchtower/internal/db"
|
||||
pba "github.com/hashicorp/watchtower/internal/gen/controller/api/resources/authtokens"
|
||||
pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/watchtower/internal/iam"
|
||||
iamStore "github.com/hashicorp/watchtower/internal/iam/store"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func getAuthMethodAndAccountId(t *testing.T, org *iam.Scope, rw *db.Db) (string, string) {
|
||||
// TODO: Remove this when Auth Account repo is in place.
|
||||
insert := `insert into auth_method
|
||||
(public_id, scope_id)
|
||||
values
|
||||
($1, $2);`
|
||||
amId, err := db.NewPublicId("am")
|
||||
require.NoError(t, err)
|
||||
innerDb, err := rw.DB()
|
||||
require.NoError(t, err)
|
||||
_, err = innerDb.Exec(insert, amId, org.GetPublicId())
|
||||
require.NoError(t, err)
|
||||
aAcctId, err := db.NewPublicId("aa")
|
||||
require.NoError(t, err)
|
||||
|
||||
aAcct := &iam.AuthAccount{AuthAccount: &iamStore.AuthAccount{
|
||||
PublicId: aAcctId,
|
||||
ScopeId: org.GetPublicId(),
|
||||
AuthMethodId: amId,
|
||||
}}
|
||||
require.NoError(t, rw.Create(context.Background(), aAcct))
|
||||
return aAcct.GetAuthMethodId(), aAcct.GetPublicId()
|
||||
}
|
||||
|
||||
func TestAuthenticate(t *testing.T) {
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
rw := db.New(conn)
|
||||
RWDb.Store(rw)
|
||||
wrapper := db.TestWrapper(t)
|
||||
o, _ := iam.TestScopes(t, conn)
|
||||
|
||||
authTokenRepoFn := func() (*authtoken.Repository, error) { return authtoken.NewRepository(rw, rw, wrapper) }
|
||||
iamRepoFn := func() (*iam.Repository, error) { return iam.NewRepository(rw, rw, wrapper) }
|
||||
amId, _ := getAuthMethodAndAccountId(t, o, rw)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
request *pbs.AuthenticateRequest
|
||||
want *pbs.AuthenticateResponse
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "basic",
|
||||
request: &pbs.AuthenticateRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
AuthMethodId: amId,
|
||||
TokenType: "token",
|
||||
Credentials: func() *structpb.Struct {
|
||||
creds := map[string]*structpb.Value{
|
||||
"name": {Kind: &structpb.Value_StringValue{StringValue: "admin"}},
|
||||
"password": {Kind: &structpb.Value_StringValue{StringValue: "hunter2"}},
|
||||
}
|
||||
return &structpb.Struct{Fields: creds}
|
||||
}(),
|
||||
},
|
||||
want: &pbs.AuthenticateResponse{Item: &pba.AuthToken{
|
||||
AuthMethodId: amId,
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "no-token-type",
|
||||
request: &pbs.AuthenticateRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
AuthMethodId: amId,
|
||||
Credentials: func() *structpb.Struct {
|
||||
creds := map[string]*structpb.Value{
|
||||
"name": {Kind: &structpb.Value_StringValue{StringValue: "admin"}},
|
||||
"password": {Kind: &structpb.Value_StringValue{StringValue: "hunter2"}},
|
||||
}
|
||||
return &structpb.Struct{Fields: creds}
|
||||
}(),
|
||||
},
|
||||
want: &pbs.AuthenticateResponse{Item: &pba.AuthToken{
|
||||
AuthMethodId: amId,
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "bad-token-type",
|
||||
request: &pbs.AuthenticateRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
AuthMethodId: amId,
|
||||
TokenType: "email",
|
||||
Credentials: func() *structpb.Struct {
|
||||
creds := map[string]*structpb.Value{
|
||||
"name": {Kind: &structpb.Value_StringValue{StringValue: "admin"}},
|
||||
"password": {Kind: &structpb.Value_StringValue{StringValue: "hunter2"}},
|
||||
}
|
||||
return &structpb.Struct{Fields: creds}
|
||||
}(),
|
||||
},
|
||||
wantErr: status.Error(codes.InvalidArgument, "invalid argument"),
|
||||
},
|
||||
{
|
||||
name: "no-authmethod",
|
||||
request: &pbs.AuthenticateRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
Credentials: func() *structpb.Struct {
|
||||
creds := map[string]*structpb.Value{
|
||||
"name": {Kind: &structpb.Value_StringValue{StringValue: "admin"}},
|
||||
"password": {Kind: &structpb.Value_StringValue{StringValue: "hunter2"}},
|
||||
}
|
||||
return &structpb.Struct{Fields: creds}
|
||||
}(),
|
||||
},
|
||||
wantErr: status.Error(codes.InvalidArgument, "invalid argument"),
|
||||
},
|
||||
{
|
||||
name: "wrong-username-password",
|
||||
request: &pbs.AuthenticateRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
AuthMethodId: amId,
|
||||
TokenType: "token",
|
||||
Credentials: func() *structpb.Struct {
|
||||
creds := map[string]*structpb.Value{
|
||||
"name": {Kind: &structpb.Value_StringValue{StringValue: "wrong"}},
|
||||
"password": {Kind: &structpb.Value_StringValue{StringValue: "wrong"}},
|
||||
}
|
||||
return &structpb.Struct{Fields: creds}
|
||||
}(),
|
||||
},
|
||||
wantErr: status.Error(codes.Unauthenticated, "unauthenticated"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
s, err := NewService(iamRepoFn, authTokenRepoFn)
|
||||
require.NoError(err)
|
||||
|
||||
// TODO: remove when we stop faking things
|
||||
name := tc.request.Credentials.Fields["name"].GetStringValue()
|
||||
acctIdBytes := sha256.Sum256([]byte(name))
|
||||
acctId := fmt.Sprintf("aa_%s", base32.StdEncoding.EncodeToString(acctIdBytes[:])[0:10])
|
||||
|
||||
aAcct := &iam.AuthAccount{AuthAccount: &iamStore.AuthAccount{
|
||||
PublicId: acctId,
|
||||
ScopeId: o.PublicId,
|
||||
AuthMethodId: amId,
|
||||
}}
|
||||
RWDb.Load().(*db.Db).Create(context.Background(), aAcct)
|
||||
|
||||
resp, err := s.Authenticate(context.Background(), tc.request)
|
||||
if tc.wantErr != nil {
|
||||
assert.Error(err)
|
||||
assert.Equal(status.Code(tc.wantErr), status.Code(err))
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
aToken := resp.GetItem()
|
||||
assert.NotEmpty(aToken.GetId())
|
||||
assert.NotEmpty(aToken.GetToken())
|
||||
assert.True(strings.HasPrefix(aToken.GetToken(), aToken.GetId()))
|
||||
assert.Equal(amId, aToken.GetAuthMethodId())
|
||||
assert.Equal(aToken.GetCreatedTime(), aToken.GetUpdatedTime())
|
||||
assert.Equal(aToken.GetCreatedTime(), aToken.GetApproximateLastUsedTime())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthenticate_AuthAccountConnectedToIamUser(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
rw := db.New(conn)
|
||||
RWDb.Store(rw)
|
||||
wrapper := db.TestWrapper(t)
|
||||
o, _ := iam.TestScopes(t, conn)
|
||||
|
||||
authTokenRepoFn := func() (*authtoken.Repository, error) { return authtoken.NewRepository(rw, rw, wrapper) }
|
||||
iamRepoFn := func() (*iam.Repository, error) { return iam.NewRepository(rw, rw, wrapper) }
|
||||
iamRepo, err := iamRepoFn()
|
||||
require.NoError(err)
|
||||
|
||||
// connected to an account.
|
||||
amId, _ := getAuthMethodAndAccountId(t, o, rw)
|
||||
|
||||
name := "admin"
|
||||
acctIdBytes := sha256.Sum256([]byte(name))
|
||||
acctId := fmt.Sprintf("aa_%s", base32.StdEncoding.EncodeToString(acctIdBytes[:])[0:10])
|
||||
|
||||
aAcct := &iam.AuthAccount{AuthAccount: &iamStore.AuthAccount{
|
||||
PublicId: acctId,
|
||||
ScopeId: o.PublicId,
|
||||
AuthMethodId: amId,
|
||||
}}
|
||||
RWDb.Load().(*db.Db).Create(context.Background(), aAcct)
|
||||
|
||||
iamUser, err := iamRepo.LookupUserWithLogin(context.Background(), acctId, iam.WithAutoVivify(true))
|
||||
require.NoError(err)
|
||||
|
||||
s, err := NewService(iamRepoFn, authTokenRepoFn)
|
||||
require.NoError(err)
|
||||
resp, err := s.Authenticate(context.Background(), &pbs.AuthenticateRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
AuthMethodId: amId,
|
||||
Credentials: func() *structpb.Struct {
|
||||
creds := map[string]*structpb.Value{
|
||||
"name": {Kind: &structpb.Value_StringValue{StringValue: name}},
|
||||
"password": {Kind: &structpb.Value_StringValue{StringValue: "hunter2"}},
|
||||
}
|
||||
return &structpb.Struct{Fields: creds}
|
||||
}(),
|
||||
})
|
||||
require.NoError(err)
|
||||
|
||||
aToken := resp.GetItem()
|
||||
assert.Equal(iamUser.GetPublicId(), aToken.GetUserId())
|
||||
assert.Equal(amId, aToken.GetAuthMethodId())
|
||||
|
||||
assert.NotEmpty(aToken.GetId())
|
||||
assert.NotEmpty(aToken.GetToken())
|
||||
assert.True(strings.HasPrefix(aToken.GetToken(), aToken.GetId()))
|
||||
}
|
||||
@@ -21,46 +21,110 @@ const (
|
||||
// TokenAuthenticator returns a function that can be used in grpc-gateway's runtime.WithMetadata ServerOption.
|
||||
// It looks at the cookies and headers of the incoming request and returns metadata that can later be
|
||||
// used by handlers to build a TokenMetadata using the ToTokenMetadata function.
|
||||
func TokenAuthenticator(l hclog.Logger, tokenRepo common.AuthTokenRepoFactory) func(context.Context, *http.Request) metadata.MD {
|
||||
func TokenAuthenticator(l hclog.Logger, tokenRepo common.AuthTokenRepoFactory, iamRepo common.IamRepoFactory) func(context.Context, *http.Request) metadata.MD {
|
||||
return func(ctx context.Context, req *http.Request) metadata.MD {
|
||||
tMD := TokenMetadata{}
|
||||
if authHeader := req.Header.Get(headerAuthMethod); authHeader != "" {
|
||||
headerSplit := strings.SplitN(strings.TrimSpace(authHeader), " ", 2)
|
||||
if len(headerSplit) == 2 && strings.EqualFold(strings.TrimSpace(headerSplit[0]), "bearer") {
|
||||
tMD.recievedTokenType = authTokenTypeBearer
|
||||
tMD.bearerPayload = strings.TrimSpace(headerSplit[1])
|
||||
return TokenMetadata{}.toMetadata()
|
||||
/*
|
||||
tMD := TokenMetadata{}
|
||||
if authHeader := req.Header.Get(headerAuthMethod); authHeader != "" {
|
||||
headerSplit := strings.SplitN(strings.TrimSpace(authHeader), " ", 2)
|
||||
if len(headerSplit) == 2 && strings.EqualFold(strings.TrimSpace(headerSplit[0]), "bearer") {
|
||||
tMD.receivedTokenType = authTokenTypeBearer
|
||||
tMD.bearerPayload = strings.TrimSpace(headerSplit[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
if tMD.recievedTokenType != authTokenTypeBearer {
|
||||
if hc, err := req.Cookie(httpOnlyCookieName); err == nil {
|
||||
tMD.httpCookiePayload = hc.Value
|
||||
if tMD.receivedTokenType != authTokenTypeBearer {
|
||||
if hc, err := req.Cookie(httpOnlyCookieName); err == nil {
|
||||
tMD.httpCookiePayload = hc.Value
|
||||
}
|
||||
if jc, err := req.Cookie(jsVisibleCookieName); err == nil {
|
||||
tMD.jsCookiePayload = jc.Value
|
||||
}
|
||||
if tMD.httpCookiePayload != "" && tMD.jsCookiePayload != "" {
|
||||
tMD.receivedTokenType = authTokenTypeSplitCookie
|
||||
}
|
||||
}
|
||||
if jc, err := req.Cookie(jsVisibleCookieName); err == nil {
|
||||
tMD.jsCookiePayload = jc.Value
|
||||
}
|
||||
if tMD.httpCookiePayload != "" && tMD.jsCookiePayload != "" {
|
||||
tMD.recievedTokenType = authTokenTypeSplitCookie
|
||||
}
|
||||
}
|
||||
|
||||
if tMD.recievedTokenType == authTokenTypeUnknown || tMD.token() == "" || tMD.publicId() == "" {
|
||||
if tMD.receivedTokenType == authTokenTypeUnknown || tMD.token() == "" || tMD.publicId() == "" {
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
|
||||
tokenRepo, err := tokenRepo()
|
||||
if err != nil {
|
||||
l.Error("failed to get authtoken repo", "error", err)
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
|
||||
at, err := tokenRepo.ValidateToken(ctx, tMD.publicId(), tMD.token())
|
||||
if err != nil {
|
||||
l.Error("failed to validate token", "error", err)
|
||||
}
|
||||
if at != nil {
|
||||
tMD.UserId = at.GetIamUserId()
|
||||
} else {
|
||||
tMD.UserId = "u_anon"
|
||||
}
|
||||
|
||||
iamRepo, err := iamRepo()
|
||||
if err != nil {
|
||||
l.Error("failed to get iam repo", "error", err)
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
grantPairs, err := iamRepo.GrantsForUser(ctx, tMD.UserId)
|
||||
if err != nil {
|
||||
l.Error("failed to query for user grants", "error", err)
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
parsedGrants := make([]perms.Grant, 0, len(grantPairs))
|
||||
for _, pair := range grantPairs {
|
||||
parsed, err := perms.Parse(pair.ScopeId, tMD.UserId, pair.Grant)
|
||||
if err != nil {
|
||||
l.Error("failed to parse grant", "grant", pair.Grant, "error", err)
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
parsedGrants = append(parsedGrants, parsed)
|
||||
}
|
||||
|
||||
var scopeId, id, pin string
|
||||
var typ resource.Type
|
||||
var act action.Type
|
||||
typRaw := ctx.Value(globals.ContextTypeValue)
|
||||
if typRaw != nil {
|
||||
typ = typRaw.(resource.Type)
|
||||
}
|
||||
scopeIdRaw := ctx.Value(globals.ContextScopeValue)
|
||||
if scopeIdRaw != nil {
|
||||
scopeId = scopeIdRaw.(string)
|
||||
}
|
||||
actRaw := ctx.Value(globals.ContextActionValue)
|
||||
if actRaw != nil {
|
||||
act = actRaw.(action.Type)
|
||||
}
|
||||
idRaw := ctx.Value(globals.ContextResourceValue)
|
||||
if idRaw != nil {
|
||||
id = idRaw.(string)
|
||||
}
|
||||
pinRaw := ctx.Value(globals.ContextPinValue)
|
||||
if pinRaw != nil {
|
||||
pin = pinRaw.(string)
|
||||
}
|
||||
|
||||
acl := perms.NewACL(parsedGrants...)
|
||||
res := perms.Resource{
|
||||
// These values were parsed from the request information
|
||||
ScopeId: scopeId,
|
||||
Type: typ,
|
||||
Id: id,
|
||||
Pin: pin,
|
||||
}
|
||||
allowed := acl.Allowed(res, act)
|
||||
if allowed.Allowed {
|
||||
tMD.authorized = true
|
||||
}
|
||||
l.Info("grant checking", "user_id", tMD.UserId, "grants", pretty.Sprint(grantPairs), "resource", res, "authorized", allowed)
|
||||
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
|
||||
repo, err := tokenRepo()
|
||||
if err != nil {
|
||||
l.Error("failed to get authtoken repo", "error", err)
|
||||
return tMD.toMetadata()
|
||||
}
|
||||
at, err := repo.ValidateToken(ctx, tMD.publicId(), tMD.token())
|
||||
if err != nil {
|
||||
l.Error("failed to validate token", "error", err)
|
||||
}
|
||||
if at != nil {
|
||||
tMD.UserId = at.GetIamUserId()
|
||||
}
|
||||
|
||||
return tMD.toMetadata()
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +151,9 @@ type TokenMetadata struct {
|
||||
// Only set the UserId if the token was found and was not expired.
|
||||
UserId string
|
||||
|
||||
recievedTokenType tokenFormat
|
||||
authorized bool
|
||||
|
||||
receivedTokenType tokenFormat
|
||||
bearerPayload string
|
||||
|
||||
jsCookiePayload string
|
||||
@@ -96,6 +162,7 @@ type TokenMetadata struct {
|
||||
|
||||
const (
|
||||
mdAuthTokenUserKey = "wt-authtoken-user-key"
|
||||
mdAuthAuthorizedKey = "wt-authtoken-authorized"
|
||||
mdAuthTokenBearerTokenKey = "wt-authtoken-bearer-token-key"
|
||||
mdAuthTokenHttpTokenKey = "wt-authtoken-http-token-key"
|
||||
mdAuthTokenJsTokenKey = "wt-authtoken-js-token-key"
|
||||
@@ -113,6 +180,9 @@ func ToTokenMetadata(ctx context.Context) TokenMetadata {
|
||||
if uid := md.Get(mdAuthTokenUserKey); len(uid) > 0 {
|
||||
tMD.UserId = uid[0]
|
||||
}
|
||||
if authzd := md.Get(mdAuthAuthorizedKey); len(authzd) > 0 {
|
||||
tMD.authorized = authzd[0] == "true"
|
||||
}
|
||||
if token := md.Get(mdAuthTokenBearerTokenKey); len(token) > 0 {
|
||||
tMD.bearerPayload = token[0]
|
||||
}
|
||||
@@ -124,7 +194,7 @@ func ToTokenMetadata(ctx context.Context) TokenMetadata {
|
||||
}
|
||||
if sType := md.Get(mdAuthTokenTypeKey); len(sType) > 0 {
|
||||
if st, err := strconv.Atoi(sType[0]); err == nil {
|
||||
tMD.recievedTokenType = tokenFormat(st)
|
||||
tMD.receivedTokenType = tokenFormat(st)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +206,11 @@ func (s TokenMetadata) toMetadata() metadata.MD {
|
||||
if s.UserId != "" {
|
||||
md.Set(mdAuthTokenUserKey, s.UserId)
|
||||
}
|
||||
if s.authorized {
|
||||
md.Set(mdAuthAuthorizedKey, "true")
|
||||
} else {
|
||||
md.Set(mdAuthAuthorizedKey, "false")
|
||||
}
|
||||
if s.bearerPayload != "" {
|
||||
md.Set(mdAuthTokenBearerTokenKey, s.bearerPayload)
|
||||
}
|
||||
@@ -145,9 +220,10 @@ func (s TokenMetadata) toMetadata() metadata.MD {
|
||||
if s.jsCookiePayload != "" {
|
||||
md.Set(mdAuthTokenJsTokenKey, s.jsCookiePayload)
|
||||
}
|
||||
if s.recievedTokenType != authTokenTypeUnknown {
|
||||
md.Set(mdAuthTokenTypeKey, fmt.Sprint(s.recievedTokenType))
|
||||
if s.receivedTokenType != authTokenTypeUnknown {
|
||||
md.Set(mdAuthTokenTypeKey, fmt.Sprint(s.receivedTokenType))
|
||||
}
|
||||
|
||||
return md
|
||||
}
|
||||
|
||||
@@ -155,7 +231,7 @@ func (s TokenMetadata) toMetadata() metadata.MD {
|
||||
// is malformed then this returns an empty string.
|
||||
func (s TokenMetadata) publicId() string {
|
||||
tok := ""
|
||||
switch s.recievedTokenType {
|
||||
switch s.receivedTokenType {
|
||||
case authTokenTypeBearer:
|
||||
tok = s.bearerPayload
|
||||
case authTokenTypeSplitCookie:
|
||||
@@ -172,7 +248,7 @@ func (s TokenMetadata) publicId() string {
|
||||
// is malformed then this returns an empty string.
|
||||
func (s TokenMetadata) token() string {
|
||||
var tok string
|
||||
switch s.recievedTokenType {
|
||||
switch s.receivedTokenType {
|
||||
case authTokenTypeBearer:
|
||||
tok = s.bearerPayload
|
||||
case authTokenTypeSplitCookie:
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/db"
|
||||
"github.com/hashicorp/watchtower/internal/gen/controller/api/services"
|
||||
pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/watchtower/internal/iam"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -30,6 +31,7 @@ func (s *fakeHandler) GetOrg(ctx context.Context, _ *pbs.GetOrgRequest) (*pbs.Ge
|
||||
}
|
||||
|
||||
func TestAuthTokenPublicIdTokenValue(t *testing.T) {
|
||||
t.Skip("functionality has moved for now")
|
||||
cases := []struct {
|
||||
name string
|
||||
in TokenMetadata
|
||||
@@ -39,7 +41,7 @@ func TestAuthTokenPublicIdTokenValue(t *testing.T) {
|
||||
{
|
||||
name: "no delimeter",
|
||||
in: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeBearer,
|
||||
receivedTokenType: authTokenTypeBearer,
|
||||
bearerPayload: "prefix_publicid_token",
|
||||
jsCookiePayload: "this_is_just_junk",
|
||||
httpCookiePayload: "this_can_be_ignored",
|
||||
@@ -50,7 +52,7 @@ func TestAuthTokenPublicIdTokenValue(t *testing.T) {
|
||||
{
|
||||
name: "no delimeter",
|
||||
in: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeSplitCookie,
|
||||
receivedTokenType: authTokenTypeSplitCookie,
|
||||
bearerPayload: "this_is_just_junk_that_should_be_ignored",
|
||||
jsCookiePayload: "prefix_publicid_token",
|
||||
httpCookiePayload: "cookiepayload",
|
||||
@@ -61,7 +63,7 @@ func TestAuthTokenPublicIdTokenValue(t *testing.T) {
|
||||
{
|
||||
name: "no delimeter",
|
||||
in: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeBearer,
|
||||
receivedTokenType: authTokenTypeBearer,
|
||||
bearerPayload: "this-doesnt-have-the-expected-delimiter",
|
||||
},
|
||||
wantId: "",
|
||||
@@ -70,7 +72,7 @@ func TestAuthTokenPublicIdTokenValue(t *testing.T) {
|
||||
{
|
||||
name: "to many delimeters",
|
||||
in: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeBearer,
|
||||
receivedTokenType: authTokenTypeBearer,
|
||||
bearerPayload: "this_has_to_many_delimiters",
|
||||
},
|
||||
wantId: "",
|
||||
@@ -87,13 +89,19 @@ func TestAuthTokenPublicIdTokenValue(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
t.Skip("functionality has moved for now")
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
rw := db.New(conn)
|
||||
wrapper := db.TestWrapper(t)
|
||||
repo, err := authtoken.NewRepository(rw, rw, wrapper)
|
||||
tokenRepo, err := authtoken.NewRepository(rw, rw, wrapper)
|
||||
require.NoError(t, err)
|
||||
repoFn := func() (*authtoken.Repository, error) {
|
||||
return repo, nil
|
||||
iamRepo, err := iam.NewRepository(rw, rw, wrapper)
|
||||
require.NoError(t, err)
|
||||
tokenRepoFn := func() (*authtoken.Repository, error) {
|
||||
return tokenRepo, nil
|
||||
}
|
||||
iamRepoFn := func() (*iam.Repository, error) {
|
||||
return iamRepo, nil
|
||||
}
|
||||
|
||||
at := authtoken.TestAuthToken(t, conn, wrapper)
|
||||
@@ -110,13 +118,13 @@ func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
{
|
||||
name: "Empty headers",
|
||||
headers: map[string]string{},
|
||||
wantAuthTokMd: TokenMetadata{recievedTokenType: authTokenTypeUnknown},
|
||||
wantAuthTokMd: TokenMetadata{receivedTokenType: authTokenTypeUnknown},
|
||||
},
|
||||
{
|
||||
name: "Bear token",
|
||||
headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", tokValue)},
|
||||
wantAuthTokMd: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeBearer,
|
||||
receivedTokenType: authTokenTypeBearer,
|
||||
bearerPayload: tokValue,
|
||||
UserId: at.GetIamUserId(),
|
||||
},
|
||||
@@ -128,7 +136,7 @@ func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
{Name: jsVisibleCookieName, Value: jsCookieVal},
|
||||
},
|
||||
wantAuthTokMd: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeSplitCookie,
|
||||
receivedTokenType: authTokenTypeSplitCookie,
|
||||
httpCookiePayload: httpCookieVal,
|
||||
jsCookiePayload: jsCookieVal,
|
||||
UserId: at.GetIamUserId(),
|
||||
@@ -140,7 +148,7 @@ func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
{Name: httpOnlyCookieName, Value: httpCookieVal},
|
||||
},
|
||||
wantAuthTokMd: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeUnknown,
|
||||
receivedTokenType: authTokenTypeUnknown,
|
||||
httpCookiePayload: httpCookieVal,
|
||||
},
|
||||
},
|
||||
@@ -150,7 +158,7 @@ func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
{Name: jsVisibleCookieName, Value: jsCookieVal},
|
||||
},
|
||||
wantAuthTokMd: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeUnknown,
|
||||
receivedTokenType: authTokenTypeUnknown,
|
||||
jsCookiePayload: jsCookieVal,
|
||||
},
|
||||
},
|
||||
@@ -163,7 +171,7 @@ func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
},
|
||||
// We prioritize the auth header over the cookie and if the header is set we ignore the cookies completely.
|
||||
wantAuthTokMd: TokenMetadata{
|
||||
recievedTokenType: authTokenTypeBearer,
|
||||
receivedTokenType: authTokenTypeBearer,
|
||||
bearerPayload: tokValue,
|
||||
UserId: at.GetIamUserId(),
|
||||
},
|
||||
@@ -176,7 +184,7 @@ func TestAuthTokenAuthenticator(t *testing.T) {
|
||||
tMD := ToTokenMetadata(ctx)
|
||||
assert.Equal(t, tc.wantAuthTokMd, tMD)
|
||||
}}
|
||||
mux := runtime.NewServeMux(runtime.WithMetadata(TokenAuthenticator(hclog.L(), repoFn)))
|
||||
mux := runtime.NewServeMux(runtime.WithMetadata(TokenAuthenticator(hclog.L(), tokenRepoFn, iamRepoFn)))
|
||||
require.NoError(t, services.RegisterOrgServiceHandlerServer(context.Background(), mux, hook))
|
||||
|
||||
req := httptest.NewRequest("GET", "http://127.0.0.1/v1/orgs/1", nil)
|
||||
|
||||
@@ -12,8 +12,6 @@ import (
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/common"
|
||||
"github.com/hashicorp/watchtower/internal/servers/controller/handlers"
|
||||
"github.com/hashicorp/watchtower/internal/types/scope"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
@@ -63,16 +61,6 @@ func (s Service) GetOrg(ctx context.Context, req *pbs.GetOrgRequest) (*pbs.GetOr
|
||||
return &pbs.GetOrgResponse{Item: o}, nil
|
||||
}
|
||||
|
||||
// Authenticate implements the interface pbs.OrgServiceServer.
|
||||
func (s Service) Authenticate(ctx context.Context, req *pbs.AuthenticateRequest) (*pbs.AuthenticateResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Requested method is unimplemented for Orgs.")
|
||||
}
|
||||
|
||||
// Deauthenticate implements the interface pbs.OrgServiceServer.
|
||||
func (s Service) Deauthenticate(ctx context.Context, req *pbs.DeauthenticateRequest) (*pbs.DeauthenticateResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Requested method is unimplemented for Orgs.")
|
||||
}
|
||||
|
||||
func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Org, error) {
|
||||
repo, err := s.repo()
|
||||
if err != nil {
|
||||
|
||||
@@ -130,7 +130,7 @@ func (s Service) AddRolePrincipals(ctx context.Context, req *pbs.AddRolePrincipa
|
||||
if err := validateAddRolePrincipalsRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := s.addPrinciplesInRepo(ctx, req.GetRoleId(), req.GetUserIds(), req.GetGroupIds(), req.GetVersion().GetValue())
|
||||
r, err := s.addPrinciplesInRepo(ctx, req.GetRoleId(), req.GetPrincipalIds(), req.GetVersion().GetValue())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -144,7 +144,7 @@ func (s Service) SetRolePrincipals(ctx context.Context, req *pbs.SetRolePrincipa
|
||||
if err := validateSetRolePrincipalsRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := s.setPrinciplesInRepo(ctx, req.GetRoleId(), req.GetUserIds(), req.GetGroupIds(), req.GetVersion().GetValue())
|
||||
r, err := s.setPrinciplesInRepo(ctx, req.GetRoleId(), req.GetPrincipalIds(), req.GetVersion().GetValue())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -158,7 +158,7 @@ func (s Service) RemoveRolePrincipals(ctx context.Context, req *pbs.RemoveRolePr
|
||||
if err := validateRemoveRolePrincipalsRequest(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err := s.removePrinciplesInRepo(ctx, req.GetRoleId(), req.GetUserIds(), req.GetGroupIds(), req.GetVersion().GetValue())
|
||||
r, err := s.removePrinciplesInRepo(ctx, req.GetRoleId(), req.GetPrincipalIds(), req.GetVersion().GetValue())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -325,12 +325,12 @@ func (s Service) listFromRepo(ctx context.Context, scopeId string) ([]*pb.Role,
|
||||
return outRl, nil
|
||||
}
|
||||
|
||||
func (s Service) addPrinciplesInRepo(ctx context.Context, roleId string, userIds []string, groupIds []string, version uint32) (*pb.Role, error) {
|
||||
func (s Service) addPrinciplesInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*pb.Role, error) {
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = repo.AddPrincipalRoles(ctx, roleId, version, userIds, groupIds)
|
||||
_, err = repo.AddPrincipalRoles(ctx, roleId, version, principalIds)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Unable to add principles to role: %v.", err)
|
||||
}
|
||||
@@ -344,12 +344,12 @@ func (s Service) addPrinciplesInRepo(ctx context.Context, roleId string, userIds
|
||||
return toProto(out, pr, roleGrants), nil
|
||||
}
|
||||
|
||||
func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, userIds []string, groupIds []string, version uint32) (*pb.Role, error) {
|
||||
func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*pb.Role, error) {
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, _, err = repo.SetPrincipalRoles(ctx, roleId, version, userIds, groupIds)
|
||||
_, _, err = repo.SetPrincipalRoles(ctx, roleId, version, principalIds)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Unable to set principles on role: %v.", err)
|
||||
}
|
||||
@@ -363,12 +363,12 @@ func (s Service) setPrinciplesInRepo(ctx context.Context, roleId string, userIds
|
||||
return toProto(out, pr, roleGrants), nil
|
||||
}
|
||||
|
||||
func (s Service) removePrinciplesInRepo(ctx context.Context, roleId string, userIds []string, groupIds []string, version uint32) (*pb.Role, error) {
|
||||
func (s Service) removePrinciplesInRepo(ctx context.Context, roleId string, principalIds []string, version uint32) (*pb.Role, error) {
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = repo.DeletePrincipalRoles(ctx, roleId, version, userIds, groupIds)
|
||||
_, err = repo.DeletePrincipalRoles(ctx, roleId, version, principalIds)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Unable to remove principles from role: %v.", err)
|
||||
}
|
||||
@@ -476,12 +476,13 @@ func toProto(in *iam.Role, principals []iam.PrincipalRole, grants []*iam.RoleGra
|
||||
out.Name = &wrapperspb.StringValue{Value: in.GetName()}
|
||||
}
|
||||
for _, p := range principals {
|
||||
switch p.GetType() {
|
||||
case iam.UserRoleType.String():
|
||||
out.UserIds = append(out.UserIds, p.GetPrincipalId())
|
||||
case iam.GroupRoleType.String():
|
||||
out.GroupIds = append(out.GroupIds, p.GetPrincipalId())
|
||||
principal := &pb.Principal{
|
||||
Id: p.GetPrincipalId(),
|
||||
Type: p.GetType(),
|
||||
ScopeId: p.GetPrincipalScopeId(),
|
||||
}
|
||||
out.Principals = append(out.Principals, principal)
|
||||
out.PrincipalIds = append(out.PrincipalIds, p.GetPrincipalId())
|
||||
}
|
||||
for _, g := range grants {
|
||||
out.Grants = append(out.Grants, g.GetRawGrant())
|
||||
@@ -542,6 +543,9 @@ func validateCreateRequest(req *pbs.CreateRoleRequest) error {
|
||||
badFields["grant_scope_id"] = "Must be empty or set to the project_id when the scope type is project."
|
||||
}
|
||||
}
|
||||
if item.GetPrincipals() != nil {
|
||||
badFields["principals"] = "This is a read only field."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Argument errors found in the request.", badFields)
|
||||
}
|
||||
@@ -572,6 +576,9 @@ func validateUpdateRequest(req *pbs.UpdateRoleRequest) error {
|
||||
if item.GetUpdatedTime() != nil {
|
||||
badFields["updated_time"] = "This is a read only field and cannot be specified in an update request."
|
||||
}
|
||||
if item.GetPrincipals() != nil {
|
||||
badFields["principals"] = "This is a read only field and cannot be specified in an update request."
|
||||
}
|
||||
if item.GetGrantScopeId() != nil && req.ProjectId != "" {
|
||||
if item.GetGrantScopeId().Value != req.ProjectId {
|
||||
badFields["grant_scope_id"] = "Must be empty or set to the project_id when the scope type is project."
|
||||
@@ -611,9 +618,8 @@ func validateAddRolePrincipalsRequest(req *pbs.AddRolePrincipalsRequest) error {
|
||||
if req.GetVersion() == nil {
|
||||
badFields["version"] = "Required field."
|
||||
}
|
||||
if len(req.GetGroupIds()) == 0 && len(req.GetUserIds()) == 0 {
|
||||
badFields["user_ids"] = "Either user_ids or group_ids must be non empty."
|
||||
badFields["group_ids"] = "Either user_ids or group_ids must be non empty."
|
||||
if len(req.GetPrincipalIds()) == 0 {
|
||||
badFields["principal_ids"] = "Must be non-empty."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
|
||||
@@ -643,9 +649,8 @@ func validateRemoveRolePrincipalsRequest(req *pbs.RemoveRolePrincipalsRequest) e
|
||||
if req.GetVersion() == nil {
|
||||
badFields["version"] = "Required field."
|
||||
}
|
||||
if len(req.GetGroupIds()) == 0 && len(req.GetUserIds()) == 0 {
|
||||
badFields["user_ids"] = "Either user_ids or group_ids must be non empty."
|
||||
badFields["group_ids"] = "Either user_ids or group_ids must be non empty."
|
||||
if len(req.GetPrincipalIds()) == 0 {
|
||||
badFields["principal_ids"] = "Must be non-empty."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
|
||||
@@ -662,7 +667,7 @@ func validateAddRoleGrantsRequest(req *pbs.AddRoleGrantsRequest) error {
|
||||
badFields["version"] = "Required field."
|
||||
}
|
||||
if len(req.GetGrants()) == 0 {
|
||||
badFields["grants"] = "This must be non empty."
|
||||
badFields["grants"] = "Must be non-empty."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
|
||||
@@ -693,7 +698,7 @@ func validateRemoveRoleGrantsRequest(req *pbs.RemoveRoleGrantsRequest) error {
|
||||
badFields["version"] = "Required field."
|
||||
}
|
||||
if len(req.GetGrants()) == 0 {
|
||||
badFields["grants"] = "This must be non empty."
|
||||
badFields["grants"] = "Must be non-empty."
|
||||
}
|
||||
if len(badFields) > 0 {
|
||||
return handlers.InvalidArgumentErrorf("Errors in provided fields.", badFields)
|
||||
|
||||
@@ -38,6 +38,30 @@ func createDefaultRolesAndRepo(t *testing.T) (*iam.Role, *iam.Role, func() (*iam
|
||||
return or, pr, repoFn
|
||||
}
|
||||
|
||||
func equalPrincipals(role *pb.Role, principals []string) bool {
|
||||
if len(role.Principals) != len(principals) {
|
||||
return false
|
||||
}
|
||||
for _, principal := range principals {
|
||||
var foundInPrincipals bool
|
||||
var foundInPrincipalIds bool
|
||||
for _, v := range role.Principals {
|
||||
if v.Id == principal {
|
||||
foundInPrincipals = true
|
||||
}
|
||||
}
|
||||
for _, v := range role.PrincipalIds {
|
||||
if v == principal {
|
||||
foundInPrincipalIds = true
|
||||
}
|
||||
}
|
||||
if !foundInPrincipals || !foundInPrincipalIds {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
@@ -891,11 +915,10 @@ func TestAddPrincipal(t *testing.T) {
|
||||
role := iam.TestRole(t, conn, scope.GetPublicId())
|
||||
tc.setup(role)
|
||||
req := &pbs.AddRolePrincipalsRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
UserIds: tc.addUsers,
|
||||
GroupIds: tc.addGroups,
|
||||
OrgId: o.GetPublicId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
PrincipalIds: append(tc.addUsers, tc.addGroups...),
|
||||
}
|
||||
|
||||
got, err := s.AddRolePrincipals(context.Background(), req)
|
||||
@@ -907,8 +930,7 @@ func TestAddPrincipal(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
require.NoError(t, err, "Got error: %v", s)
|
||||
|
||||
assert.ElementsMatch(t, got.GetItem().GetUserIds(), tc.resultUsers)
|
||||
assert.ElementsMatch(t, got.GetItem().GetGroupIds(), tc.resultGroups)
|
||||
assert.True(t, equalPrincipals(got.GetItem(), append(tc.resultUsers, tc.resultGroups...)))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -926,7 +948,6 @@ func TestAddPrincipal(t *testing.T) {
|
||||
OrgId: "",
|
||||
ProjectId: role.GetScopeId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -937,7 +958,6 @@ func TestAddPrincipal(t *testing.T) {
|
||||
OrgId: o.GetPublicId(),
|
||||
ProjectId: "bad id",
|
||||
RoleId: role.GetPublicId(),
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -948,7 +968,6 @@ func TestAddPrincipal(t *testing.T) {
|
||||
OrgId: o.GetPublicId(),
|
||||
ProjectId: role.GetScopeId(),
|
||||
RoleId: "bad id",
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -1039,11 +1058,10 @@ func TestSetPrincipal(t *testing.T) {
|
||||
role := iam.TestRole(t, conn, scope.GetPublicId())
|
||||
tc.setup(role)
|
||||
req := &pbs.SetRolePrincipalsRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
UserIds: tc.setUsers,
|
||||
GroupIds: tc.setGroups,
|
||||
OrgId: o.GetPublicId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
PrincipalIds: append(tc.setUsers, tc.setGroups...),
|
||||
}
|
||||
|
||||
got, err := s.SetRolePrincipals(context.Background(), req)
|
||||
@@ -1055,8 +1073,7 @@ func TestSetPrincipal(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
require.NoError(t, err, "Got error: %v", s)
|
||||
|
||||
assert.Equal(t, got.GetItem().GetUserIds(), tc.resultUsers)
|
||||
assert.Equal(t, got.GetItem().GetGroupIds(), tc.resultGroups)
|
||||
assert.True(t, equalPrincipals(got.GetItem(), append(tc.resultUsers, tc.resultGroups...)))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1074,7 +1091,6 @@ func TestSetPrincipal(t *testing.T) {
|
||||
OrgId: "",
|
||||
ProjectId: role.GetScopeId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -1085,7 +1101,6 @@ func TestSetPrincipal(t *testing.T) {
|
||||
OrgId: o.GetPublicId(),
|
||||
ProjectId: "bad id",
|
||||
RoleId: role.GetPublicId(),
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -1096,7 +1111,6 @@ func TestSetPrincipal(t *testing.T) {
|
||||
OrgId: o.GetPublicId(),
|
||||
ProjectId: role.GetScopeId(),
|
||||
RoleId: "bad id",
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -1205,11 +1219,10 @@ func TestRemovePrincipal(t *testing.T) {
|
||||
role := iam.TestRole(t, conn, scope.GetPublicId())
|
||||
tc.setup(role)
|
||||
req := &pbs.RemoveRolePrincipalsRequest{
|
||||
OrgId: o.GetPublicId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
UserIds: tc.removeUsers,
|
||||
GroupIds: tc.removeGroups,
|
||||
OrgId: o.GetPublicId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
PrincipalIds: append(tc.removeUsers, tc.removeGroups...),
|
||||
}
|
||||
|
||||
got, err := s.RemoveRolePrincipals(context.Background(), req)
|
||||
@@ -1221,8 +1234,7 @@ func TestRemovePrincipal(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
require.NoError(t, err, "Got error: %v", s)
|
||||
|
||||
assert.ElementsMatch(t, got.GetItem().GetUserIds(), tc.resultUsers)
|
||||
assert.ElementsMatch(t, got.GetItem().GetGroupIds(), tc.resultGroups)
|
||||
assert.True(t, equalPrincipals(got.GetItem(), append(tc.resultUsers, tc.resultGroups...)))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1240,7 +1252,6 @@ func TestRemovePrincipal(t *testing.T) {
|
||||
OrgId: "",
|
||||
ProjectId: role.GetScopeId(),
|
||||
RoleId: role.GetPublicId(),
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -1251,7 +1262,6 @@ func TestRemovePrincipal(t *testing.T) {
|
||||
OrgId: o.GetPublicId(),
|
||||
ProjectId: "bad id",
|
||||
RoleId: role.GetPublicId(),
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
@@ -1262,7 +1272,6 @@ func TestRemovePrincipal(t *testing.T) {
|
||||
OrgId: o.GetPublicId(),
|
||||
ProjectId: role.GetScopeId(),
|
||||
RoleId: "bad id",
|
||||
GroupIds: []string{},
|
||||
Version: &wrapperspb.UInt32Value{Value: role.GetVersion()},
|
||||
},
|
||||
errCode: codes.InvalidArgument,
|
||||
|
||||
@@ -120,6 +120,11 @@ type TestControllerOpts struct {
|
||||
|
||||
// If true, the controller will not be started
|
||||
DisableAutoStart bool
|
||||
|
||||
// DisableAuthorizationFailures will still cause authz checks to be
|
||||
// performed but they won't cause 403 Forbidden. Useful for API-level
|
||||
// testing to avoid a lot of faff.
|
||||
DisableAuthorizationFailures bool
|
||||
}
|
||||
|
||||
func NewTestController(t *testing.T, opts *TestControllerOpts) *TestController {
|
||||
@@ -183,8 +188,9 @@ func NewTestController(t *testing.T, opts *TestControllerOpts) *TestController {
|
||||
}
|
||||
|
||||
conf := &Config{
|
||||
RawConfig: opts.Config,
|
||||
Server: tc.b,
|
||||
RawConfig: opts.Config,
|
||||
Server: tc.b,
|
||||
DisableAuthorizationFailures: opts.DisableAuthorizationFailures,
|
||||
}
|
||||
|
||||
tc.c, err = New(conf)
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/watchtower/internal/cmd/base"
|
||||
"github.com/hashicorp/watchtower/internal/cmd/config"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
*base.Server
|
||||
RawConfig *config.Config
|
||||
BaseContext context.Context
|
||||
RawConfig *config.Config
|
||||
}
|
||||
@@ -21,24 +21,25 @@ const (
|
||||
AddPrincipals Type = 12
|
||||
SetPrincipals Type = 13
|
||||
RemovePrincipals Type = 14
|
||||
Deauthenticate Type = 15
|
||||
)
|
||||
|
||||
var Map = map[string]Type{
|
||||
"unknown": Unknown,
|
||||
"list": List,
|
||||
"create": Create,
|
||||
"update": Update,
|
||||
"read": Read,
|
||||
"delete": Delete,
|
||||
"authenticate": Authenticate,
|
||||
"*": All,
|
||||
"connect": Connect,
|
||||
"add-grants": AddGrants,
|
||||
"remove-grants": RemoveGrants,
|
||||
"set-grants": SetGrants,
|
||||
"add-principals": AddPrincipals,
|
||||
"set-principals": SetPrincipals,
|
||||
"remove-principals": RemovePrincipals,
|
||||
Create.String(): Create,
|
||||
List.String(): List,
|
||||
Update.String(): Update,
|
||||
Read.String(): Read,
|
||||
Delete.String(): Delete,
|
||||
Authenticate.String(): Authenticate,
|
||||
All.String(): All,
|
||||
Connect.String(): Connect,
|
||||
AddGrants.String(): AddGrants,
|
||||
RemoveGrants.String(): RemoveGrants,
|
||||
SetGrants.String(): SetGrants,
|
||||
AddPrincipals.String(): AddPrincipals,
|
||||
SetPrincipals.String(): SetPrincipals,
|
||||
RemovePrincipals.String(): RemovePrincipals,
|
||||
Deauthenticate.String(): Deauthenticate,
|
||||
}
|
||||
|
||||
func (a Type) String() string {
|
||||
@@ -58,5 +59,6 @@ func (a Type) String() string {
|
||||
"add-principals",
|
||||
"set-principals",
|
||||
"remove-principals",
|
||||
"deauthenticate",
|
||||
}[a]
|
||||
}
|
||||
@@ -71,6 +71,10 @@ func TestAction(t *testing.T) {
|
||||
action: SetPrincipals,
|
||||
want: "set-principals",
|
||||
},
|
||||
{
|
||||
action: Deauthenticate,
|
||||
want: "deauthenticate",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.want, func(t *testing.T) {
|
||||
|
||||
@@ -24,6 +24,9 @@ const (
|
||||
Host Type = 17
|
||||
Target Type = 18
|
||||
Global Type = 19
|
||||
|
||||
// TODO: remove this after demo
|
||||
Group Type = 20
|
||||
)
|
||||
|
||||
func (r Type) String() string {
|
||||
@@ -48,50 +51,29 @@ func (r Type) String() string {
|
||||
"host",
|
||||
"target",
|
||||
"global",
|
||||
"group",
|
||||
}[r]
|
||||
}
|
||||
|
||||
func StringToResourceType(s string) Type {
|
||||
switch s {
|
||||
case Scope.String():
|
||||
return Scope
|
||||
case User.String():
|
||||
return User
|
||||
case StaticGroup.String():
|
||||
return StaticGroup
|
||||
case Role.String():
|
||||
return Role
|
||||
case Org.String():
|
||||
return Org
|
||||
case StaticGroupMember.String():
|
||||
return StaticGroupMember
|
||||
case StaticGroupUserMember.String():
|
||||
return StaticGroupUserMember
|
||||
case AssignedRole.String():
|
||||
return AssignedRole
|
||||
case AssignedUserRole.String():
|
||||
return AssignedUserRole
|
||||
case AssignedStaticGroupRole.String():
|
||||
return AssignedStaticGroupRole
|
||||
case RoleGrant.String():
|
||||
return RoleGrant
|
||||
case AuthMethod.String():
|
||||
return AuthMethod
|
||||
case Project.String():
|
||||
return Project
|
||||
case All.String():
|
||||
return All
|
||||
case HostCatalog.String():
|
||||
return HostCatalog
|
||||
case HostSet.String():
|
||||
return HostSet
|
||||
case Host.String():
|
||||
return Host
|
||||
case Target.String():
|
||||
return Target
|
||||
case Global.String():
|
||||
return Global
|
||||
default:
|
||||
return Unknown
|
||||
}
|
||||
var Map = map[string]Type{
|
||||
Scope.String(): Scope,
|
||||
User.String(): User,
|
||||
StaticGroup.String(): StaticGroup,
|
||||
Role.String(): Role,
|
||||
Org.String(): Org,
|
||||
StaticGroupMember.String(): StaticGroupMember,
|
||||
StaticGroupUserMember.String(): StaticGroupUserMember,
|
||||
AssignedRole.String(): AssignedRole,
|
||||
AssignedUserRole.String(): AssignedUserRole,
|
||||
AssignedStaticGroupRole.String(): AssignedStaticGroupRole,
|
||||
RoleGrant.String(): RoleGrant,
|
||||
AuthMethod.String(): AuthMethod,
|
||||
Project.String(): Project,
|
||||
All.String(): All,
|
||||
HostCatalog.String(): HostCatalog,
|
||||
HostSet.String(): HostSet,
|
||||
Host.String(): Host,
|
||||
Target.String(): Target,
|
||||
Global.String(): Global,
|
||||
Group.String(): Group,
|
||||
}
|
||||
@@ -95,7 +95,7 @@ func Test_Resource(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.typeString, func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, StringToResourceType(tt.typeString), "unexpected type for %s", tt.typeString)
|
||||
assert.Equalf(t, tt.want, Map[tt.typeString], "unexpected type for %s", tt.typeString)
|
||||
assert.Equalf(t, tt.typeString, tt.want.String(), "unexpected string for %s", tt.typeString)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,15 +28,8 @@ func (s Type) Prefix() string {
|
||||
}[s]
|
||||
}
|
||||
|
||||
func StringToScopeType(s string) Type {
|
||||
switch s {
|
||||
case Global.String():
|
||||
return Global
|
||||
case Org.String():
|
||||
return Org
|
||||
case Project.String():
|
||||
return Project
|
||||
default:
|
||||
return Unknown
|
||||
}
|
||||
var Map = map[string]Type{
|
||||
Global.String(): Global,
|
||||
Org.String(): Org,
|
||||
Project.String(): Project,
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_StringToScopeType(t *testing.T) {
|
||||
func Test_Map(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
s string
|
||||
@@ -41,7 +41,7 @@ func Test_StringToScopeType(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
got := StringToScopeType(tt.s)
|
||||
got := Map[tt.s]
|
||||
assert.Equal(tt.want, got)
|
||||
assert.Equalf(tt.wantPrefix, got.Prefix(), "unexpected prefix for %s", tt.s)
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user