diff --git a/rgw/admin/user_test.go b/rgw/admin/user_test.go index be83497c7..79760d9ce 100644 --- a/rgw/admin/user_test.go +++ b/rgw/admin/user_test.go @@ -36,7 +36,12 @@ var ( "email": "", "suspended": 0, "max_buckets": 1000, - "subusers": [], + "subusers": [ + { + "id": "dashboard-admin:swift", + "permissions": "read" + } + ], "keys": [ { "user": "dashboard-admin", @@ -44,7 +49,12 @@ var ( "secret_key": "YSaT5bEcJTjBJCDG5yvr2NhGQ9xzoTIg8B1gQHa3" } ], - "swift_keys": [], + "swift_keys": [ + { + "user": "dashboard-admin:swift", + "secret_key": "VERY_SECRET" + } + ], "caps": [], "op_mask": "read, write, delete", "system": "true", @@ -74,10 +84,21 @@ var ( func TestUnmarshal(t *testing.T) { u := &User{} + // XXX: add subuser-foo to the fake-response err := json.Unmarshal(fakeUserResponse, &u) assert.NoError(t, err) } +func TestValidateSubuserAccess(t *testing.T) { + assert.True(t, SubuserSpec{Access: SubuserAccessNone}.validateSubuserAccess()) + assert.True(t, SubuserSpec{Access: SubuserAccessRead}.validateSubuserAccess()) + assert.True(t, SubuserSpec{Access: SubuserAccessWrite}.validateSubuserAccess()) + assert.True(t, SubuserSpec{Access: SubuserAccessReadWrite}.validateSubuserAccess()) + assert.True(t, SubuserSpec{Access: SubuserAccessFull}.validateSubuserAccess()) + assert.False(t, SubuserSpec{Access: SubuserAccessReplyFull}.validateSubuserAccess()) + assert.False(t, SubuserSpec{Access: SubuserAccess("bar")}.validateSubuserAccess()) +} + func (suite *RadosGWTestSuite) TestUser() { suite.SetupConnection() co, err := New(suite.endpoint, suite.accessKey, suite.secretKey, newDebugHTTPClient(http.DefaultClient)) @@ -164,12 +185,82 @@ func (suite *RadosGWTestSuite) TestUser() { assert.NotNil(suite.T(), user.Stat.Size) }) + suite.T().Run("create a subuser", func(t *testing.T) { + err := co.CreateSubuser(context.Background(), User{ID: "leseb"}, SubuserSpec{Name: "foo", Access: SubuserAccessReadWrite}) + assert.NoError(suite.T(), err) + + user, err := co.GetUser(context.Background(), User{ID: "leseb"}) + assert.NoError(suite.T(), err) + if err == nil { + assert.Equal(suite.T(), user.Subusers[0].Name, "leseb:foo") + // Note: the returned values are not equal to the input values ... + assert.Equal(suite.T(), user.Subusers[0].Access, SubuserAccess("read-write")) + } + }) + + suite.T().Run("modify a subuser", func(t *testing.T) { + err := co.ModifySubuser(context.Background(), User{ID: "leseb"}, SubuserSpec{Name: "foo", Access: SubuserAccessRead}) + assert.NoError(suite.T(), err) + + user, err := co.GetUser(context.Background(), User{ID: "leseb"}) + assert.NoError(suite.T(), err) + if err == nil { + assert.Equal(suite.T(), user.Subusers[0].Name, "leseb:foo") + assert.Equal(suite.T(), user.Subusers[0].Access, SubuserAccess("read")) + } + }) + + suite.T().Run("remove a subuser", func(t *testing.T) { + err := co.RemoveSubuser(context.Background(), User{ID: "leseb"}, SubuserSpec{Name: "foo"}) + assert.NoError(suite.T(), err) + + user, err := co.GetUser(context.Background(), User{ID: "leseb"}) + assert.NoError(suite.T(), err) + if err == nil { + assert.Equal(suite.T(), len(user.Subusers), 0) + } + }) + suite.T().Run("remove user", func(t *testing.T) { err = co.RemoveUser(context.Background(), User{ID: "leseb"}) assert.NoError(suite.T(), err) }) } +func TestCreateSubuserMockAPI(t *testing.T) { + t.Run("test create subuser validation: neither is set", func(t *testing.T) { + api, err := New("127.0.0.1", "accessKey", "secretKey", returnMockClientCreateSubuser()) + assert.NoError(t, err) + err = api.CreateSubuser(context.TODO(), User{}, SubuserSpec{}) + assert.Equal(t, err, errMissingUserID) + }) + t.Run("test create subuser validation: no user ID", func(t *testing.T) { + api, err := New("127.0.0.1", "accessKey", "secretKey", returnMockClientCreateSubuser()) + assert.NoError(t, err) + err = api.CreateSubuser(context.TODO(), User{}, SubuserSpec{Name: "foo"}) + assert.Equal(t, err, errMissingUserID) + }) + t.Run("test create subuser validation: no subuser ID", func(t *testing.T) { + api, err := New("127.0.0.1", "accessKey", "secretKey", returnMockClientCreateSubuser()) + assert.NoError(t, err) + err = api.CreateSubuser(context.TODO(), User{ID: "dashboard-admin"}, SubuserSpec{}) + assert.Equal(t, err, errMissingSubuserID) + }) + t.Run("test create subuser validation: valid", func(t *testing.T) { + api, err := New("127.0.0.1", "accessKey", "secretKey", returnMockClientCreateSubuser()) + assert.NoError(t, err) + err = api.CreateSubuser(context.TODO(), User{ID: "dashboard-admin"}, SubuserSpec{Name: "foo"}) + assert.NoError(t, err) + }) + t.Run("test create subuser validation: invalid access", func(t *testing.T) { + api, err := New("127.0.0.1", "accessKey", "secretKey", returnMockClientCreateSubuser()) + assert.NoError(t, err) + err = api.CreateSubuser(context.TODO(), User{ID: "dashboard-admin"}, SubuserSpec{Name: "foo", Access: SubuserAccess("foo")}) + assert.Error(t, err) + assert.EqualError(t, err, `invalid subuser access level "foo"`) + }) +} + func TestGetUserMockAPI(t *testing.T) { t.Run("test simple api mock", func(t *testing.T) { api, err := New("127.0.0.1", "accessKey", "secretKey", returnMockClient()) @@ -215,3 +306,18 @@ func returnMockClient() *mockClient { }, } } + +func returnMockClientCreateSubuser() *mockClient { + r := ioutil.NopCloser(bytes.NewReader([]byte(""))) + return &mockClient{ + mockDo: func(req *http.Request) (*http.Response, error) { + if req.Method == http.MethodPut && req.URL.Path == "127.0.0.1/admin/user" { + return &http.Response{ + StatusCode: 201, + Body: r, + }, nil + } + return nil, fmt.Errorf("unexpected request: %q. method %q. path %q", req.URL.RawQuery, req.Method, req.URL.Path) + }, + } +}