Skip to content

Commit

Permalink
feat(http): allow user id to be specified explicitly on authorization
Browse files Browse the repository at this point in the history
test(http): get user off of session in create authz test

fix(http): allow user id to be specified explicitly on authorization

create authorization now allows specifying user id explicitly. If no
user id is specified then we use the user id from the authorizer.

fix(http): use influxdb import

fix(http): use platform error in http auth tests

feat(cmd/influx): allow create auth command to specify user explicitly

feat(http): add org id to permissions
  • Loading branch information
desa committed Jan 14, 2019
1 parent 32c63cd commit c62895b
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 10 deletions.
2 changes: 1 addition & 1 deletion auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Authorization struct {
Status Status `json:"status"`
Description string `json:"description"`
OrgID ID `json:"orgID"`
UserID ID `json:"userID"`
UserID ID `json:"userID,omitempty"`
Permissions []Permission `json:"permissions"`
}

Expand Down
20 changes: 18 additions & 2 deletions cmd/influx/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ func init() {
authorizationCreateCmd.Flags().StringVarP(&authorizationCreateFlags.org, "org", "o", "", "org name (required)")
authorizationCreateCmd.MarkFlagRequired("org")

authorizationCreateCmd.Flags().StringVarP(&authorizationCreateFlags.user, "user", "u", "", "user name (required)")
authorizationCreateCmd.MarkFlagRequired("user")
authorizationCreateCmd.Flags().StringVarP(&authorizationCreateFlags.user, "user", "u", "", "user name")

authorizationCreateCmd.Flags().BoolVarP(&authorizationCreateFlags.writeUserPermission, "write-user", "", false, "grants the permission to perform mutative actions against organization users")
authorizationCreateCmd.Flags().BoolVarP(&authorizationCreateFlags.readUserPermission, "read-user", "", false, "grants the permission to perform read actions against organization users")
Expand Down Expand Up @@ -229,6 +228,23 @@ func authorizationCreateF(cmd *cobra.Command, args []string) error {
OrgID: o.ID,
}

if authorizationCreateFlags.user != "" {
// if the user flag is supplied, the set the user ID explicitly on the request
userSvc, err := newUserService(flags)
if err != nil {
return err
}
userFilter := platform.UserFilter{
Name: &authorizationCreateFlags.user,
}
user, err := userSvc.FindUser(context.Background(), userFilter)
if err != nil {
return err
}

authorization.UserID = user.ID
}

s, err := newAuthorizationService(flags)
if err != nil {
return err
Expand Down
30 changes: 25 additions & 5 deletions http/auth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,25 @@ func (h *AuthorizationHandler) handlePostAuthorization(w http.ResponseWriter, r
return
}

user, err := getAuthorizedUser(r, h.UserService)
if err != nil {
EncodeError(ctx, platform.ErrUnableToCreateToken, w)
return
var user *platform.User
// allow the user id to be specified optionally, if it is not set
// we use the id from the authorizer
if req.UserID == nil {
u, err := getAuthorizedUser(r, h.UserService)
if err != nil {
EncodeError(ctx, platform.ErrUnableToCreateToken, w)
return
}

user = u
} else {
u, err := h.UserService.FindUserByID(ctx, *req.UserID)
if err != nil {
EncodeError(ctx, platform.ErrUnableToCreateToken, w)
return
}

user = u
}

auth := req.toPlatform(user.ID)
Expand All @@ -167,14 +182,15 @@ func (h *AuthorizationHandler) handlePostAuthorization(w http.ResponseWriter, r
}

if err := encodeResponse(ctx, w, http.StatusCreated, newAuthResponse(auth, org, user, perms)); err != nil {
EncodeError(ctx, err, w)
logEncodingError(h.Logger, r, err)
return
}
}

type postAuthorizationRequest struct {
Status platform.Status `json:"status"`
OrgID platform.ID `json:"orgID"`
UserID *platform.ID `json:"userID,omitempty"`
Description string `json:"description"`
Permissions []platform.Permission `json:"permissions"`
}
Expand All @@ -197,6 +213,10 @@ func newPostAuthorizationRequest(a *platform.Authorization) (*postAuthorizationR
Status: a.Status,
}

if a.UserID.Valid() {
res.UserID = &a.UserID
}

res.SetDefaults()

return res, res.Validate()
Expand Down
104 changes: 102 additions & 2 deletions http/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import (
platform "github.com/influxdata/influxdb"
pcontext "github.com/influxdata/influxdb/context"
"github.com/influxdata/influxdb/inmem"
"github.com/influxdata/influxdb/kit/errors"
"github.com/influxdata/influxdb/mock"

platformtesting "github.com/influxdata/influxdb/testing"
"github.com/julienschmidt/httprouter"
)
Expand Down Expand Up @@ -398,6 +400,9 @@ func TestService_handlePostAuthorization(t *testing.T) {
},
UserService: &mock.UserService{
FindUserByIDFn: func(ctx context.Context, id platform.ID) (*platform.User, error) {
if !id.Valid() {
return nil, platform.ErrInvalidID
}
return &platform.User{
ID: id,
Name: "u1",
Expand All @@ -406,6 +411,9 @@ func TestService_handlePostAuthorization(t *testing.T) {
},
OrganizationService: &mock.OrganizationService{
FindOrganizationByIDF: func(ctx context.Context, id platform.ID) (*platform.Organization, error) {
if !id.Valid() {
return nil, platform.ErrInvalidID
}
return &platform.Organization{
ID: id,
Name: "o1",
Expand All @@ -430,7 +438,6 @@ func TestService_handlePostAuthorization(t *testing.T) {
},
authorization: &platform.Authorization{
ID: platformtesting.MustIDBase16("020f755c3c082000"),
UserID: platformtesting.MustIDBase16("aaaaaaaaaaaaaaaa"),
OrgID: platformtesting.MustIDBase16("020f755c3c083000"),
Description: "only read dashboards sucka",
Permissions: []platform.Permission{
Expand Down Expand Up @@ -467,6 +474,95 @@ func TestService_handlePostAuthorization(t *testing.T) {
"user": "u1",
"userID": "aaaaaaaaaaaaaaaa"
}
`,
},
},
{
name: "create a new authorization with user id set explicitly",
fields: fields{
AuthorizationService: &mock.AuthorizationService{
CreateAuthorizationFn: func(ctx context.Context, c *platform.Authorization) error {
c.ID = platformtesting.MustIDBase16("020f755c3c082000")
c.Token = "new-test-token"
return nil
},
},
UserService: &mock.UserService{
FindUserByIDFn: func(ctx context.Context, id platform.ID) (*platform.User, error) {
if !id.Valid() {
return nil, errors.New("invalid user ID")
}
return &platform.User{
ID: id,
Name: "u1",
}, nil
},
},
OrganizationService: &mock.OrganizationService{
FindOrganizationByIDF: func(ctx context.Context, id platform.ID) (*platform.Organization, error) {
if !id.Valid() {
return nil, errors.New("invalid org ID")
}
return &platform.Organization{
ID: id,
Name: "o1",
}, nil
},
},
},
args: args{
session: &platform.Authorization{
Token: "session-token",
ID: platformtesting.MustIDBase16("020f755c3c082000"),
UserID: platformtesting.MustIDBase16("aaaaaaaaaaaaaaaa"),
OrgID: platformtesting.MustIDBase16("020f755c3c083000"),
Description: "can write to authorization resource",
Permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.AuthorizationsResource,
},
},
},
authorization: &platform.Authorization{
ID: platformtesting.MustIDBase16("020f755c3c082000"),
UserID: platformtesting.MustIDBase16("bbbbbbbbbbbbbbbb"),
OrgID: platformtesting.MustIDBase16("020f755c3c083000"),
Description: "only read dashboards sucka",
Permissions: []platform.Permission{
{
Action: platform.ReadAction,
Resource: platform.DashboardsResource,
OrgID: platformtesting.MustIDBase16("020f755c3c083000"),
},
},
},
},
wants: wants{
statusCode: http.StatusCreated,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"user": "/api/v2/users/bbbbbbbbbbbbbbbb",
"self": "/api/v2/authorizations/020f755c3c082000"
},
"id": "020f755c3c082000",
"user": "u1",
"userID": "bbbbbbbbbbbbbbbb",
"orgID": "020f755c3c083000",
"org": "o1",
"token": "new-test-token",
"status": "active",
"description": "only read dashboards sucka",
"permissions": [
{
"action": "read",
"orgID": "020f755c3c083000",
"resource": "dashboards"
}
]
}
`,
},
},
Expand All @@ -479,7 +575,11 @@ func TestService_handlePostAuthorization(t *testing.T) {
h.UserService = tt.fields.UserService
h.OrganizationService = tt.fields.OrganizationService

b, err := json.Marshal(tt.args.authorization)
req, err := newPostAuthorizationRequest(tt.args.authorization)
if err != nil {
t.Fatalf("failed to create new authorization request: %v", err)
}
b, err := json.Marshal(req)
if err != nil {
t.Fatalf("failed to unmarshal authorization: %v", err)
}
Expand Down

0 comments on commit c62895b

Please sign in to comment.