Merge pull request #712 from influxdata/feature/enable-disable-auth
feat(auth): allow authorizations to be enabled/disabledpull/10616/head
commit
6897d0878a
43
auth.go
43
auth.go
|
@ -9,11 +9,32 @@ import (
|
||||||
type Authorization struct {
|
type Authorization struct {
|
||||||
ID ID `json:"id"`
|
ID ID `json:"id"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
Status Status `json:"status"`
|
||||||
User string `json:"user,omitempty"`
|
User string `json:"user,omitempty"`
|
||||||
UserID ID `json:"userID,omitempty"`
|
UserID ID `json:"userID,omitempty"`
|
||||||
Permissions []Permission `json:"permissions"`
|
Permissions []Permission `json:"permissions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allowed returns true if the authorization is active and requested permission level
|
||||||
|
// exists in the authorization's list of permissions.
|
||||||
|
func Allowed(req Permission, auth *Authorization) bool {
|
||||||
|
if !IsActive(auth) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range auth.Permissions {
|
||||||
|
if p.Action == req.Action && p.Resource == req.Resource {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsActive returns true if the authorization active.
|
||||||
|
func IsActive(auth *Authorization) bool {
|
||||||
|
return auth.Status == Active
|
||||||
|
}
|
||||||
|
|
||||||
// AuthorizationService represents a service for managing authorization data.
|
// AuthorizationService represents a service for managing authorization data.
|
||||||
type AuthorizationService interface {
|
type AuthorizationService interface {
|
||||||
// Returns a single authorization by ID.
|
// Returns a single authorization by ID.
|
||||||
|
@ -29,6 +50,10 @@ type AuthorizationService interface {
|
||||||
// Creates a new authorization and sets a.Token and a.UserID with the new identifier.
|
// Creates a new authorization and sets a.Token and a.UserID with the new identifier.
|
||||||
CreateAuthorization(ctx context.Context, a *Authorization) error
|
CreateAuthorization(ctx context.Context, a *Authorization) error
|
||||||
|
|
||||||
|
// SetAuthorizationStatus updates the status of the authorization. Useful
|
||||||
|
// for setting an authorization to inactive or active.
|
||||||
|
SetAuthorizationStatus(ctx context.Context, id ID, status Status) error
|
||||||
|
|
||||||
// Removes a authorization by token.
|
// Removes a authorization by token.
|
||||||
DeleteAuthorization(ctx context.Context, id ID) error
|
DeleteAuthorization(ctx context.Context, id ID) error
|
||||||
}
|
}
|
||||||
|
@ -85,19 +110,19 @@ func (p Permission) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// CreateUser is a permission for creating users.
|
// CreateUserPermission is a permission for creating users.
|
||||||
CreateUserPermission = Permission{
|
CreateUserPermission = Permission{
|
||||||
Action: CreateAction,
|
Action: CreateAction,
|
||||||
Resource: UserResource,
|
Resource: UserResource,
|
||||||
}
|
}
|
||||||
// DeleteUser is a permission for deleting users.
|
// DeleteUserPermission is a permission for deleting users.
|
||||||
DeleteUserPermission = Permission{
|
DeleteUserPermission = Permission{
|
||||||
Action: DeleteAction,
|
Action: DeleteAction,
|
||||||
Resource: UserResource,
|
Resource: UserResource,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadBucket constructs a permission for reading a bucket.
|
// ReadBucketPermission constructs a permission for reading a bucket.
|
||||||
func ReadBucketPermission(id ID) Permission {
|
func ReadBucketPermission(id ID) Permission {
|
||||||
return Permission{
|
return Permission{
|
||||||
Action: ReadAction,
|
Action: ReadAction,
|
||||||
|
@ -105,20 +130,10 @@ func ReadBucketPermission(id ID) Permission {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteBucket constructs a permission for writing to a bucket.
|
// WriteBucketPermission constructs a permission for writing to a bucket.
|
||||||
func WriteBucketPermission(id ID) Permission {
|
func WriteBucketPermission(id ID) Permission {
|
||||||
return Permission{
|
return Permission{
|
||||||
Action: WriteAction,
|
Action: WriteAction,
|
||||||
Resource: BucketResource(id),
|
Resource: BucketResource(id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allowed returns true if the permission exists in a list of permissions.
|
|
||||||
func Allowed(req Permission, ps []Permission) bool {
|
|
||||||
for _, p := range ps {
|
|
||||||
if p.Action == req.Action && p.Resource == req.Resource {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ func (c *Client) findAuthorizationByID(ctx context.Context, tx *bolt.Tx, id plat
|
||||||
return nil, fmt.Errorf("authorization not found")
|
return nil, fmt.Errorf("authorization not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(v, &a); err != nil {
|
if err := decodeAuthorization(v, &a); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,9 +221,20 @@ func (c *Client) PutAuthorization(ctx context.Context, a *platform.Authorization
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) putAuthorization(ctx context.Context, tx *bolt.Tx, a *platform.Authorization) error {
|
func encodeAuthorization(a *platform.Authorization) ([]byte, error) {
|
||||||
a.User = ""
|
a.User = ""
|
||||||
v, err := json.Marshal(a)
|
switch a.Status {
|
||||||
|
case platform.Active, platform.Inactive:
|
||||||
|
case "":
|
||||||
|
a.Status = platform.Active
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown authorization status")
|
||||||
|
}
|
||||||
|
return json.Marshal(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) putAuthorization(ctx context.Context, tx *bolt.Tx, a *platform.Authorization) error {
|
||||||
|
v, err := encodeAuthorization(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -232,6 +243,7 @@ func (c *Client) putAuthorization(ctx context.Context, tx *bolt.Tx, a *platform.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tx.Bucket(authorizationBucket).Put(a.ID, v); err != nil {
|
if err := tx.Bucket(authorizationBucket).Put(a.ID, v); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return c.setUserOnAuthorization(ctx, tx, a)
|
return c.setUserOnAuthorization(ctx, tx, a)
|
||||||
}
|
}
|
||||||
|
@ -240,12 +252,23 @@ func authorizationIndexKey(n string) []byte {
|
||||||
return []byte(n)
|
return []byte(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeAuthorization(b []byte, a *platform.Authorization) error {
|
||||||
|
if err := json.Unmarshal(b, a); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if a.Status == "" {
|
||||||
|
a.Status = platform.Active
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// forEachAuthorization will iterate through all authorizations while fn returns true.
|
// forEachAuthorization will iterate through all authorizations while fn returns true.
|
||||||
func (c *Client) forEachAuthorization(ctx context.Context, tx *bolt.Tx, fn func(*platform.Authorization) bool) error {
|
func (c *Client) forEachAuthorization(ctx context.Context, tx *bolt.Tx, fn func(*platform.Authorization) bool) error {
|
||||||
cur := tx.Bucket(authorizationBucket).Cursor()
|
cur := tx.Bucket(authorizationBucket).Cursor()
|
||||||
for k, v := cur.First(); k != nil; k, v = cur.Next() {
|
for k, v := cur.First(); k != nil; k, v = cur.Next() {
|
||||||
a := &platform.Authorization{}
|
a := &platform.Authorization{}
|
||||||
if err := json.Unmarshal(v, a); err != nil {
|
|
||||||
|
if err := decodeAuthorization(v, a); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.setUserOnAuthorization(ctx, tx, a); err != nil {
|
if err := c.setUserOnAuthorization(ctx, tx, a); err != nil {
|
||||||
|
@ -281,3 +304,26 @@ func (c *Client) deleteAuthorization(ctx context.Context, tx *bolt.Tx, id platfo
|
||||||
}
|
}
|
||||||
return tx.Bucket(authorizationBucket).Delete(id)
|
return tx.Bucket(authorizationBucket).Delete(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAuthorizationStatus updates the status of the authorization. Useful
|
||||||
|
// for setting an authorization to inactive or active.
|
||||||
|
func (c *Client) SetAuthorizationStatus(ctx context.Context, id platform.ID, status platform.Status) error {
|
||||||
|
return c.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
return c.updateAuthorization(ctx, tx, id, status)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) updateAuthorization(ctx context.Context, tx *bolt.Tx, id platform.ID, status platform.Status) error {
|
||||||
|
a, err := c.findAuthorizationByID(ctx, tx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Status = status
|
||||||
|
b, err := encodeAuthorization(a)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Bucket(authorizationBucket).Put(a.ID, b)
|
||||||
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ func authorizationCreateF(cmd *cobra.Command, args []string) {
|
||||||
w.WriteHeaders(
|
w.WriteHeaders(
|
||||||
"ID",
|
"ID",
|
||||||
"Token",
|
"Token",
|
||||||
|
"Status",
|
||||||
"User",
|
"User",
|
||||||
"UserID",
|
"UserID",
|
||||||
"Permissions",
|
"Permissions",
|
||||||
|
@ -111,6 +112,7 @@ func authorizationCreateF(cmd *cobra.Command, args []string) {
|
||||||
w.Write(map[string]interface{}{
|
w.Write(map[string]interface{}{
|
||||||
"ID": authorization.ID.String(),
|
"ID": authorization.ID.String(),
|
||||||
"Token": authorization.Token,
|
"Token": authorization.Token,
|
||||||
|
"Status": authorization.Status,
|
||||||
"User": authorization.User,
|
"User": authorization.User,
|
||||||
"UserID": authorization.UserID.String(),
|
"UserID": authorization.UserID.String(),
|
||||||
"Permissions": ps,
|
"Permissions": ps,
|
||||||
|
@ -178,6 +180,7 @@ func authorizationFindF(cmd *cobra.Command, args []string) {
|
||||||
w.WriteHeaders(
|
w.WriteHeaders(
|
||||||
"ID",
|
"ID",
|
||||||
"Token",
|
"Token",
|
||||||
|
"Status",
|
||||||
"User",
|
"User",
|
||||||
"UserID",
|
"UserID",
|
||||||
"Permissions",
|
"Permissions",
|
||||||
|
@ -192,6 +195,7 @@ func authorizationFindF(cmd *cobra.Command, args []string) {
|
||||||
w.Write(map[string]interface{}{
|
w.Write(map[string]interface{}{
|
||||||
"ID": a.ID,
|
"ID": a.ID,
|
||||||
"Token": a.Token,
|
"Token": a.Token,
|
||||||
|
"Status": a.Status,
|
||||||
"User": a.User,
|
"User": a.User,
|
||||||
"UserID": a.UserID.String(),
|
"UserID": a.UserID.String(),
|
||||||
"Permissions": permissions,
|
"Permissions": permissions,
|
||||||
|
@ -269,3 +273,143 @@ func authorizationDeleteF(cmd *cobra.Command, args []string) {
|
||||||
})
|
})
|
||||||
w.Flush()
|
w.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthorizationActiveFlags are command line args used when enabling an authorization
|
||||||
|
type AuthorizationActiveFlags struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
var authorizationActiveFlags AuthorizationActiveFlags
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
authorizationActiveCmd := &cobra.Command{
|
||||||
|
Use: "active",
|
||||||
|
Short: "active authorization",
|
||||||
|
Run: authorizationActiveF,
|
||||||
|
}
|
||||||
|
|
||||||
|
authorizationActiveCmd.Flags().StringVarP(&authorizationActiveFlags.id, "id", "i", "", "authorization id (required)")
|
||||||
|
authorizationActiveCmd.MarkFlagRequired("id")
|
||||||
|
|
||||||
|
authorizationCmd.AddCommand(authorizationActiveCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func authorizationActiveF(cmd *cobra.Command, args []string) {
|
||||||
|
s := &http.AuthorizationService{
|
||||||
|
Addr: flags.host,
|
||||||
|
Token: flags.token,
|
||||||
|
}
|
||||||
|
|
||||||
|
id := platform.ID{}
|
||||||
|
if err := id.DecodeFromString(authorizationActiveFlags.id); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
a, err := s.FindAuthorizationByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.SetAuthorizationStatus(context.Background(), id, platform.Active); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := internal.NewTabWriter(os.Stdout)
|
||||||
|
w.WriteHeaders(
|
||||||
|
"ID",
|
||||||
|
"Token",
|
||||||
|
"Status",
|
||||||
|
"User",
|
||||||
|
"UserID",
|
||||||
|
"Permissions",
|
||||||
|
)
|
||||||
|
|
||||||
|
ps := []string{}
|
||||||
|
for _, p := range a.Permissions {
|
||||||
|
ps = append(ps, p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(map[string]interface{}{
|
||||||
|
"ID": a.ID.String(),
|
||||||
|
"Token": a.Token,
|
||||||
|
"Status": a.Status,
|
||||||
|
"User": a.User,
|
||||||
|
"UserID": a.UserID.String(),
|
||||||
|
"Permissions": ps,
|
||||||
|
})
|
||||||
|
w.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizationInactiveFlags are command line args used when disabling an authorization
|
||||||
|
type AuthorizationInactiveFlags struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
var authorizationInactiveFlags AuthorizationInactiveFlags
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
authorizationInactiveCmd := &cobra.Command{
|
||||||
|
Use: "inactive",
|
||||||
|
Short: "inactive authorization",
|
||||||
|
Run: authorizationInactiveF,
|
||||||
|
}
|
||||||
|
|
||||||
|
authorizationInactiveCmd.Flags().StringVarP(&authorizationInactiveFlags.id, "id", "i", "", "authorization id (required)")
|
||||||
|
authorizationInactiveCmd.MarkFlagRequired("id")
|
||||||
|
|
||||||
|
authorizationCmd.AddCommand(authorizationInactiveCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func authorizationInactiveF(cmd *cobra.Command, args []string) {
|
||||||
|
s := &http.AuthorizationService{
|
||||||
|
Addr: flags.host,
|
||||||
|
Token: flags.token,
|
||||||
|
}
|
||||||
|
|
||||||
|
id := platform.ID{}
|
||||||
|
if err := id.DecodeFromString(authorizationInactiveFlags.id); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
a, err := s.FindAuthorizationByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.SetAuthorizationStatus(context.Background(), id, platform.Inactive); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := internal.NewTabWriter(os.Stdout)
|
||||||
|
w.WriteHeaders(
|
||||||
|
"ID",
|
||||||
|
"Token",
|
||||||
|
"Status",
|
||||||
|
"User",
|
||||||
|
"UserID",
|
||||||
|
"Permissions",
|
||||||
|
)
|
||||||
|
|
||||||
|
ps := []string{}
|
||||||
|
for _, p := range a.Permissions {
|
||||||
|
ps = append(ps, p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(map[string]interface{}{
|
||||||
|
"ID": a.ID.String(),
|
||||||
|
"Token": a.Token,
|
||||||
|
"Status": a.Status,
|
||||||
|
"User": a.User,
|
||||||
|
"UserID": a.UserID.String(),
|
||||||
|
"Permissions": ps,
|
||||||
|
})
|
||||||
|
w.Flush()
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ func NewAuthorizationHandler() *AuthorizationHandler {
|
||||||
h.HandlerFunc("POST", "/v1/authorizations", h.handlePostAuthorization)
|
h.HandlerFunc("POST", "/v1/authorizations", h.handlePostAuthorization)
|
||||||
h.HandlerFunc("GET", "/v1/authorizations", h.handleGetAuthorizations)
|
h.HandlerFunc("GET", "/v1/authorizations", h.handleGetAuthorizations)
|
||||||
h.HandlerFunc("GET", "/v1/authorizations/:id", h.handleGetAuthorization)
|
h.HandlerFunc("GET", "/v1/authorizations/:id", h.handleGetAuthorization)
|
||||||
|
h.HandlerFunc("PATCH", "/v1/authorizations/:id", h.handleSetAuthorizationStatus)
|
||||||
h.HandlerFunc("DELETE", "/v1/authorizations/:id", h.handleDeleteAuthorization)
|
h.HandlerFunc("DELETE", "/v1/authorizations/:id", h.handleDeleteAuthorization)
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
@ -181,6 +182,72 @@ func decodeGetAuthorizationRequest(ctx context.Context, r *http.Request) (*getAu
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleSetAuthorizationStatus is the HTTP handler for the PATCH /v1/authorizations/:id route that updates the authorization's status.
|
||||||
|
func (h *AuthorizationHandler) handleSetAuthorizationStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
req, err := decodeSetAuthorizationStatusRequest(ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
h.Logger.Info("failed to decode request", zap.String("handler", "updateAuthorization"), zap.Error(err))
|
||||||
|
EncodeError(ctx, err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a, err := h.AuthorizationService.FindAuthorizationByID(ctx, req.ID)
|
||||||
|
if err != nil {
|
||||||
|
EncodeError(ctx, err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Status != a.Status {
|
||||||
|
a.Status = req.Status
|
||||||
|
if err := h.AuthorizationService.SetAuthorizationStatus(ctx, a.ID, a.Status); err != nil {
|
||||||
|
EncodeError(ctx, err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := encodeResponse(ctx, w, http.StatusOK, a); err != nil {
|
||||||
|
h.Logger.Info("failed to encode response", zap.String("handler", "updateAuthorization"), zap.Error(err))
|
||||||
|
EncodeError(ctx, err, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type updateAuthorizationRequest struct {
|
||||||
|
ID platform.ID
|
||||||
|
Status platform.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSetAuthorizationStatusRequest(ctx context.Context, r *http.Request) (*updateAuthorizationRequest, error) {
|
||||||
|
params := httprouter.ParamsFromContext(ctx)
|
||||||
|
id := params.ByName("id")
|
||||||
|
if id == "" {
|
||||||
|
return nil, kerrors.InvalidDataf("url missing id")
|
||||||
|
}
|
||||||
|
|
||||||
|
var i platform.ID
|
||||||
|
if err := i.DecodeFromString(id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
a := &setAuthorizationStatusRequest{}
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(a); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch a.Status {
|
||||||
|
case platform.Active, platform.Inactive:
|
||||||
|
default:
|
||||||
|
return nil, kerrors.InvalidDataf("unknown status option")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &updateAuthorizationRequest{
|
||||||
|
ID: i,
|
||||||
|
Status: a.Status,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleDeleteAuthorization is the HTTP handler for the DELETE /v1/authorizations/:id route.
|
// handleDeleteAuthorization is the HTTP handler for the DELETE /v1/authorizations/:id route.
|
||||||
func (h *AuthorizationHandler) handleDeleteAuthorization(w http.ResponseWriter, r *http.Request) {
|
func (h *AuthorizationHandler) handleDeleteAuthorization(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
@ -231,6 +298,7 @@ type AuthorizationService struct {
|
||||||
|
|
||||||
var _ platform.AuthorizationService = (*AuthorizationService)(nil)
|
var _ platform.AuthorizationService = (*AuthorizationService)(nil)
|
||||||
|
|
||||||
|
// FindAuthorizationByID finds the authorization against a remote influx server.
|
||||||
func (s *AuthorizationService) FindAuthorizationByID(ctx context.Context, id platform.ID) (*platform.Authorization, error) {
|
func (s *AuthorizationService) FindAuthorizationByID(ctx context.Context, id platform.ID) (*platform.Authorization, error) {
|
||||||
u, err := newURL(s.Addr, authorizationIDPath(id))
|
u, err := newURL(s.Addr, authorizationIDPath(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -241,7 +309,7 @@ func (s *AuthorizationService) FindAuthorizationByID(ctx context.Context, id pla
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -295,7 +363,7 @@ func (s *AuthorizationService) FindAuthorizations(ctx context.Context, filter pl
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.RawQuery = query.Encode()
|
req.URL.RawQuery = query.Encode()
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -338,7 +406,7 @@ func (s *AuthorizationService) CreateAuthorization(ctx context.Context, a *platf
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -359,6 +427,46 @@ func (s *AuthorizationService) CreateAuthorization(ctx context.Context, a *platf
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type setAuthorizationStatusRequest struct {
|
||||||
|
Status platform.Status `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAuthorizationStatus updates an authorization's status.
|
||||||
|
func (s *AuthorizationService) SetAuthorizationStatus(ctx context.Context, id platform.ID, status platform.Status) error {
|
||||||
|
u, err := newURL(s.Addr, authorizationIDPath(id))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(setAuthorizationStatusRequest{
|
||||||
|
Status: status,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PATCH", u.String(), bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
resp, err := hc.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := CheckError(resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteAuthorization removes a authorization by id.
|
// DeleteAuthorization removes a authorization by id.
|
||||||
func (s *AuthorizationService) DeleteAuthorization(ctx context.Context, id platform.ID) error {
|
func (s *AuthorizationService) DeleteAuthorization(ctx context.Context, id platform.ID) error {
|
||||||
u, err := newURL(s.Addr, authorizationIDPath(id))
|
u, err := newURL(s.Addr, authorizationIDPath(id))
|
||||||
|
@ -370,7 +478,7 @@ func (s *AuthorizationService) DeleteAuthorization(ctx context.Context, id platf
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
|
|
@ -281,7 +281,7 @@ func (s *BucketService) FindBucketByID(ctx context.Context, id platform.ID) (*pl
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -344,7 +344,7 @@ func (s *BucketService) FindBuckets(ctx context.Context, filter platform.BucketF
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.RawQuery = query.Encode()
|
req.URL.RawQuery = query.Encode()
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -383,7 +383,7 @@ func (s *BucketService) CreateBucket(ctx context.Context, b *platform.Bucket) er
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ func (s *BucketService) UpdateBucket(ctx context.Context, id platform.ID, upd pl
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ func (s *BucketService) DeleteBucket(ctx context.Context, id platform.ID) error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
|
|
@ -298,7 +298,7 @@ func (s *OrganizationService) FindOrganizations(ctx context.Context, filter plat
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -341,7 +341,7 @@ func (s *OrganizationService) CreateOrganization(ctx context.Context, o *platfor
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ func (s *OrganizationService) UpdateOrganization(ctx context.Context, id platfor
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ func (s *OrganizationService) DeleteOrganization(ctx context.Context, id platfor
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
|
|
@ -143,7 +143,7 @@ func (h *PlatformHandler) PrometheusCollectors() []prometheus.Collector {
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractAuthorization(ctx context.Context, r *nethttp.Request) (context.Context, error) {
|
func extractAuthorization(ctx context.Context, r *nethttp.Request) (context.Context, error) {
|
||||||
t, err := ParseAuthHeaderToken(r)
|
t, err := GetToken(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, err
|
return ctx, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ func (s *ProxyQueryService) Query(ctx context.Context, w io.Writer, req *query.P
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
hreq.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, hreq)
|
||||||
hreq = hreq.WithContext(ctx)
|
hreq = hreq.WithContext(ctx)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
|
@ -139,7 +139,7 @@ func (s *QueryService) Query(ctx context.Context, req *query.Request) (query.Res
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hreq.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, hreq)
|
||||||
hreq = hreq.WithContext(ctx)
|
hreq = hreq.WithContext(ctx)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
|
@ -467,7 +467,7 @@ func (s *SourceService) FindSourceByID(ctx context.Context, id platform.ID) (*pl
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -501,7 +501,7 @@ func (s *SourceService) FindSources(ctx context.Context, opt platform.FindOption
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -540,7 +540,7 @@ func (s *SourceService) CreateSource(ctx context.Context, b *platform.Source) er
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ func (s *SourceService) UpdateSource(ctx context.Context, id platform.ID, upd pl
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ func (s *SourceService) DeleteSource(ctx context.Context, id platform.ID) error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
hc := newClient(u.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
|
|
@ -901,7 +901,7 @@ paths:
|
||||||
patch:
|
patch:
|
||||||
tags:
|
tags:
|
||||||
- Authorizations
|
- Authorizations
|
||||||
summary: enable/disable authorization
|
summary: update authorization to be active or inactive. requests using an inactive authorization will be rejected.
|
||||||
requestBody:
|
requestBody:
|
||||||
description: authorization to update to apply
|
description: authorization to update to apply
|
||||||
required: true
|
required: true
|
||||||
|
@ -918,7 +918,7 @@ paths:
|
||||||
description: ID of authorization to update
|
description: ID of authorization to update
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: the enabled or disabled authorization
|
description: the active or inactie authorization
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
|
@ -1846,9 +1846,13 @@ components:
|
||||||
id:
|
id:
|
||||||
readOnly: true
|
readOnly: true
|
||||||
type: string
|
type: string
|
||||||
disabled:
|
status:
|
||||||
description: if true the token has been disabled and requests will be rejected.
|
description: if inactive the token is inactive and requests using the token will be rejected.
|
||||||
type: boolean
|
default: active
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- active
|
||||||
|
- inactive
|
||||||
token:
|
token:
|
||||||
readOnly: true
|
readOnly: true
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -2,20 +2,21 @@ package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tokenScheme = "Token "
|
const tokenScheme = "Token " // TODO(goller): I'd like this to be Bearer
|
||||||
|
|
||||||
// errors
|
// errors
|
||||||
var (
|
var (
|
||||||
ErrAuthHeaderMissing = errors.New("Authorization Header is missing")
|
ErrAuthHeaderMissing = errors.New("Authorization Header is missing")
|
||||||
ErrAuthBadScheme = errors.New("Authorization Header Scheme has to Token")
|
ErrAuthBadScheme = errors.New("Authorization Header Scheme is invalid")
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseAuthHeaderToken will parse the token from http Authorization Header.
|
// GetToken will parse the token from http Authorization Header.
|
||||||
func ParseAuthHeaderToken(r *http.Request) (string, error) {
|
func GetToken(r *http.Request) (string, error) {
|
||||||
header := r.Header.Get("Authorization")
|
header := r.Header.Get("Authorization")
|
||||||
if header == "" {
|
if header == "" {
|
||||||
return "", ErrAuthHeaderMissing
|
return "", ErrAuthHeaderMissing
|
||||||
|
@ -25,3 +26,8 @@ func ParseAuthHeaderToken(r *http.Request) (string, error) {
|
||||||
}
|
}
|
||||||
return header[len(tokenScheme):], nil
|
return header[len(tokenScheme):], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetToken adds the token to the request.
|
||||||
|
func SetToken(token string, req *http.Request) {
|
||||||
|
req.Header.Set("Authorization", fmt.Sprintf("%s%s", tokenScheme, token))
|
||||||
|
}
|
|
@ -2,10 +2,19 @@ package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParseAuthHeader(t *testing.T) {
|
func tokenRequest(token string) *http.Request {
|
||||||
|
req := httptest.NewRequest("GET", "/", nil)
|
||||||
|
if token != "" {
|
||||||
|
SetToken(token, req)
|
||||||
|
}
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetToken(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
header string
|
header string
|
||||||
}
|
}
|
||||||
|
@ -62,7 +71,7 @@ func TestParseAuthHeader(t *testing.T) {
|
||||||
Header: make(http.Header),
|
Header: make(http.Header),
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", tt.args.header)
|
req.Header.Set("Authorization", tt.args.header)
|
||||||
result, err := ParseAuthHeaderToken(req)
|
result, err := GetToken(req)
|
||||||
if err != tt.wants.err {
|
if err != tt.wants.err {
|
||||||
t.Errorf("err incorrect want %v, got %v", tt.wants.err, err)
|
t.Errorf("err incorrect want %v, got %v", tt.wants.err, err)
|
||||||
return
|
return
|
||||||
|
@ -74,3 +83,27 @@ func TestParseAuthHeader(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetToken(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
token string
|
||||||
|
req *http.Request
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "adding token to Authorization header",
|
||||||
|
token: "1234",
|
||||||
|
req: httptest.NewRequest("GET", "/", nil),
|
||||||
|
want: "Token 1234",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
SetToken(tt.token, tt.req)
|
||||||
|
if got := tt.req.Header.Get("Authorization"); got != tt.want {
|
||||||
|
t.Errorf("SetToken() want %s, got %s", tt.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -265,7 +265,7 @@ func (s *UserService) FindUserByID(ctx context.Context, id platform.ID) (*platfo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -322,7 +322,7 @@ func (s *UserService) FindUsers(ctx context.Context, filter platform.UserFilter,
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.RawQuery = query.Encode()
|
req.URL.RawQuery = query.Encode()
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
@ -364,7 +364,7 @@ func (s *UserService) CreateUser(ctx context.Context, u *platform.User) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ func (s *UserService) UpdateUser(ctx context.Context, id platform.ID, upd platfo
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ func (s *UserService) DeleteUser(ctx context.Context, id platform.ID) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set("Authorization", s.Token)
|
SetToken(s.Token, req)
|
||||||
|
|
||||||
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
hc := newClient(url.Scheme, s.InsecureSkipVerify)
|
||||||
resp, err := hc.Do(req)
|
resp, err := hc.Do(req)
|
||||||
|
|
|
@ -109,6 +109,22 @@ func (s *AuthorizationService) DeleteAuthorization(ctx context.Context, id platf
|
||||||
return s.AuthorizationService.DeleteAuthorization(ctx, id)
|
return s.AuthorizationService.DeleteAuthorization(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAuthorizationStatus updates the status of the authorization. Useful
|
||||||
|
// for setting an authorization to inactive or active.
|
||||||
|
func (s *AuthorizationService) SetAuthorizationStatus(ctx context.Context, id platform.ID, status platform.Status) (err error) {
|
||||||
|
defer func(start time.Time) {
|
||||||
|
labels := prometheus.Labels{
|
||||||
|
"method": "setAuthorizationStatus",
|
||||||
|
"error": fmt.Sprint(err != nil),
|
||||||
|
}
|
||||||
|
s.requestCount.With(labels).Add(1)
|
||||||
|
s.requestDuration.With(labels).Observe(time.Since(start).Seconds())
|
||||||
|
}(time.Now())
|
||||||
|
|
||||||
|
return s.AuthorizationService.SetAuthorizationStatus(ctx, id, status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrometheusCollectors returns all authorization service prometheus collectors.
|
||||||
func (s *AuthorizationService) PrometheusCollectors() []prometheus.Collector {
|
func (s *AuthorizationService) PrometheusCollectors() []prometheus.Collector {
|
||||||
return []prometheus.Collector{
|
return []prometheus.Collector{
|
||||||
s.requestCount,
|
s.requestCount,
|
||||||
|
|
|
@ -38,6 +38,10 @@ func (a *authzSvc) DeleteAuthorization(context.Context, platform.ID) error {
|
||||||
return a.Err
|
return a.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *authzSvc) SetAuthorizationStatus(context.Context, platform.ID, platform.Status) error {
|
||||||
|
return a.Err
|
||||||
|
}
|
||||||
|
|
||||||
func TestAuthorizationService_Metrics(t *testing.T) {
|
func TestAuthorizationService_Metrics(t *testing.T) {
|
||||||
a := new(authzSvc)
|
a := new(authzSvc)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package platform
|
||||||
|
|
||||||
|
// Status defines if a resource is active or inactive.
|
||||||
|
type Status string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Active status means that the resource can be used.
|
||||||
|
Active Status = "active"
|
||||||
|
// Inactive status means that the resource cannot be used.
|
||||||
|
Inactive Status = "inactive"
|
||||||
|
)
|
|
@ -47,7 +47,7 @@ func validatePermission(ctx context.Context, perm platform.Permission) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !platform.Allowed(perm, auth.Permissions) {
|
if !platform.Allowed(perm, auth) {
|
||||||
return authError{error: ErrFailedPermission, perm: perm, auth: auth}
|
return authError{error: ErrFailedPermission, perm: perm, auth: auth}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ func CreateAuthorization(
|
||||||
ID: idFromString(t, authOneID),
|
ID: idFromString(t, authOneID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
Token: "rand",
|
Token: "rand",
|
||||||
|
Status: platform.Active,
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
|
@ -146,6 +147,7 @@ func CreateAuthorization(
|
||||||
ID: idFromString(t, authOneID),
|
ID: idFromString(t, authOneID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
|
Status: platform.Active,
|
||||||
Token: "supersecret",
|
Token: "supersecret",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
|
@ -155,6 +157,7 @@ func CreateAuthorization(
|
||||||
{
|
{
|
||||||
ID: idFromString(t, authTwoID),
|
ID: idFromString(t, authTwoID),
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
|
Status: platform.Active,
|
||||||
User: "regularuser",
|
User: "regularuser",
|
||||||
Token: "rand",
|
Token: "rand",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
|
@ -254,6 +257,7 @@ func FindAuthorizationByID(
|
||||||
ID: idFromString(t, authTwoID),
|
ID: idFromString(t, authTwoID),
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
User: "regularuser",
|
User: "regularuser",
|
||||||
|
Status: platform.Active,
|
||||||
Token: "rand2",
|
Token: "rand2",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
|
@ -324,6 +328,7 @@ func FindAuthorizationByToken(
|
||||||
ID: idFromString(t, authOneID),
|
ID: idFromString(t, authOneID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
Token: "rand1",
|
Token: "rand1",
|
||||||
|
Status: platform.Inactive,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
platform.DeleteUserPermission,
|
platform.DeleteUserPermission,
|
||||||
|
@ -364,6 +369,7 @@ func FindAuthorizationByToken(
|
||||||
authorization: &platform.Authorization{
|
authorization: &platform.Authorization{
|
||||||
ID: idFromString(t, authOneID),
|
ID: idFromString(t, authOneID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
|
Status: platform.Inactive,
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
Token: "rand1",
|
Token: "rand1",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
|
@ -446,6 +452,7 @@ func FindAuthorizations(
|
||||||
{
|
{
|
||||||
ID: idFromString(t, authTwoID),
|
ID: idFromString(t, authTwoID),
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
|
Status: platform.Active,
|
||||||
Token: "rand2",
|
Token: "rand2",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
|
@ -461,6 +468,7 @@ func FindAuthorizations(
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
Token: "rand1",
|
Token: "rand1",
|
||||||
|
Status: platform.Active,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
platform.DeleteUserPermission,
|
platform.DeleteUserPermission,
|
||||||
|
@ -471,6 +479,7 @@ func FindAuthorizations(
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
User: "regularuser",
|
User: "regularuser",
|
||||||
Token: "rand2",
|
Token: "rand2",
|
||||||
|
Status: platform.Active,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
},
|
},
|
||||||
|
@ -496,6 +505,7 @@ func FindAuthorizations(
|
||||||
ID: idFromString(t, authOneID),
|
ID: idFromString(t, authOneID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
Token: "rand1",
|
Token: "rand1",
|
||||||
|
Status: platform.Active,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
platform.DeleteUserPermission,
|
platform.DeleteUserPermission,
|
||||||
|
@ -528,6 +538,7 @@ func FindAuthorizations(
|
||||||
ID: idFromString(t, authOneID),
|
ID: idFromString(t, authOneID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
|
Status: platform.Active,
|
||||||
Token: "rand1",
|
Token: "rand1",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
|
@ -538,6 +549,7 @@ func FindAuthorizations(
|
||||||
ID: idFromString(t, authThreeID),
|
ID: idFromString(t, authThreeID),
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
|
Status: platform.Active,
|
||||||
Token: "rand3",
|
Token: "rand3",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.DeleteUserPermission,
|
platform.DeleteUserPermission,
|
||||||
|
@ -605,6 +617,7 @@ func FindAuthorizations(
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
User: "regularuser",
|
User: "regularuser",
|
||||||
Token: "rand2",
|
Token: "rand2",
|
||||||
|
Status: platform.Active,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
},
|
},
|
||||||
|
@ -710,6 +723,7 @@ func DeleteAuthorization(
|
||||||
ID: idFromString(t, authTwoID),
|
ID: idFromString(t, authTwoID),
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
User: "regularuser",
|
User: "regularuser",
|
||||||
|
Status: platform.Active,
|
||||||
Token: "rand2",
|
Token: "rand2",
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
|
@ -762,6 +776,7 @@ func DeleteAuthorization(
|
||||||
UserID: idFromString(t, userOneID),
|
UserID: idFromString(t, userOneID),
|
||||||
User: "cooluser",
|
User: "cooluser",
|
||||||
Token: "rand1",
|
Token: "rand1",
|
||||||
|
Status: platform.Active,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
platform.DeleteUserPermission,
|
platform.DeleteUserPermission,
|
||||||
|
@ -772,6 +787,7 @@ func DeleteAuthorization(
|
||||||
UserID: idFromString(t, userTwoID),
|
UserID: idFromString(t, userTwoID),
|
||||||
User: "regularuser",
|
User: "regularuser",
|
||||||
Token: "rand2",
|
Token: "rand2",
|
||||||
|
Status: platform.Active,
|
||||||
Permissions: []platform.Permission{
|
Permissions: []platform.Permission{
|
||||||
platform.CreateUserPermission,
|
platform.CreateUserPermission,
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"github.com/influxdata/platform"
|
"github.com/influxdata/platform"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ platform.AuthorizationService = (*AuthorizationService)(nil)
|
||||||
|
|
||||||
// AuthorizationService manages authorizations.
|
// AuthorizationService manages authorizations.
|
||||||
type AuthorizationService struct {
|
type AuthorizationService struct {
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
|
@ -68,3 +70,14 @@ func (s *AuthorizationService) DeleteAuthorization(ctx context.Context, id platf
|
||||||
|
|
||||||
return s.AuthorizationService.DeleteAuthorization(ctx, id)
|
return s.AuthorizationService.DeleteAuthorization(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAuthorizationStatus updates an authorization's status and logs any errors.
|
||||||
|
func (s *AuthorizationService) SetAuthorizationStatus(ctx context.Context, id platform.ID, status platform.Status) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
s.Logger.Info("error updating authorization", zap.Error(err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return s.AuthorizationService.SetAuthorizationStatus(ctx, id, status)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue