Adding support for listing user roles
diff --git a/openstack/identity/v2/users/fixtures.go b/openstack/identity/v2/users/fixtures.go
index 2e72b87..796bc1a 100644
--- a/openstack/identity/v2/users/fixtures.go
+++ b/openstack/identity/v2/users/fixtures.go
@@ -136,3 +136,28 @@
w.WriteHeader(http.StatusNoContent)
})
}
+
+func MockListRolesResponse(t *testing.T) {
+ th.Mux.HandleFunc("/tenants/1d8b6120dcc640fda4fc9194ffc80273/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+
+ fmt.Fprintf(w, `
+{
+ "roles": [
+ {
+ "id": "9fe2ff9ee4384b1894a90878d3e92bab",
+ "name": "foo_role"
+ },
+ {
+ "id": "1ea3d56793574b668e85960fbf651e13",
+ "name": "admin"
+ }
+ ]
+}
+ `)
+ })
+}
diff --git a/openstack/identity/v2/users/requests.go b/openstack/identity/v2/users/requests.go
index bcf86c5..d0c2fdd 100644
--- a/openstack/identity/v2/users/requests.go
+++ b/openstack/identity/v2/users/requests.go
@@ -168,3 +168,11 @@
return result
}
+
+func ListRoles(client *gophercloud.ServiceClient, tenantID, userID string) pagination.Pager {
+ createPage := func(r pagination.PageResult) pagination.Page {
+ return RolePage{pagination.SinglePageBase(r)}
+ }
+
+ return pagination.NewPager(client, listRolesURL(client, tenantID, userID), createPage)
+}
diff --git a/openstack/identity/v2/users/requests_test.go b/openstack/identity/v2/users/requests_test.go
index a47ad64..462732f 100644
--- a/openstack/identity/v2/users/requests_test.go
+++ b/openstack/identity/v2/users/requests_test.go
@@ -137,3 +137,29 @@
res := Delete(client.ServiceClient(), "c39e3de9be2d4c779f1dfd6abacc176d")
th.AssertNoErr(t, res.Err)
}
+
+func TestListingUserRoles(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ MockListRolesResponse(t)
+
+ tenantID := "1d8b6120dcc640fda4fc9194ffc80273"
+ userID := "c39e3de9be2d4c779f1dfd6abacc176d"
+
+ err := ListRoles(client.ServiceClient(), tenantID, userID).EachPage(func(page pagination.Page) (bool, error) {
+ actual, err := ExtractRoles(page)
+ th.AssertNoErr(t, err)
+
+ expected := []Role{
+ Role{ID: "9fe2ff9ee4384b1894a90878d3e92bab", Name: "foo_role"},
+ Role{ID: "1ea3d56793574b668e85960fbf651e13", Name: "admin"},
+ }
+
+ th.CheckDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+
+ th.AssertNoErr(t, err)
+}
diff --git a/openstack/identity/v2/users/results.go b/openstack/identity/v2/users/results.go
index 262b8c8..f531d5d 100644
--- a/openstack/identity/v2/users/results.go
+++ b/openstack/identity/v2/users/results.go
@@ -28,11 +28,26 @@
TenantID string `mapstructure:"tenant_id"`
}
+// Role assigns specific responsibilities to users, allowing them to accomplish
+// certain API operations whilst scoped to a service.
+type Role struct {
+ // UUID of the role
+ ID string
+
+ // Name of the role
+ Name string
+}
+
// UserPage is a single page of a User collection.
type UserPage struct {
pagination.SinglePageBase
}
+// RolePage is a single page of a user Role collection.
+type RolePage struct {
+ pagination.SinglePageBase
+}
+
// IsEmpty determines whether or not a page of Tenants contains any results.
func (page UserPage) IsEmpty() (bool, error) {
users, err := ExtractUsers(page)
@@ -53,6 +68,26 @@
return response.Users, err
}
+// IsEmpty determines whether or not a page of Tenants contains any results.
+func (page RolePage) IsEmpty() (bool, error) {
+ users, err := ExtractRoles(page)
+ if err != nil {
+ return false, err
+ }
+ return len(users) == 0, nil
+}
+
+// ExtractRoles returns a slice of Roles contained in a single page of results.
+func ExtractRoles(page pagination.Page) ([]Role, error) {
+ casted := page.(RolePage).Body
+ var response struct {
+ Roles []Role `mapstructure:"roles"`
+ }
+
+ err := mapstructure.Decode(casted, &response)
+ return response.Roles, err
+}
+
type commonResult struct {
gophercloud.Result
}
diff --git a/openstack/identity/v2/users/urls.go b/openstack/identity/v2/users/urls.go
index 41b3435..f59cafc 100644
--- a/openstack/identity/v2/users/urls.go
+++ b/openstack/identity/v2/users/urls.go
@@ -2,12 +2,19 @@
import "github.com/rackspace/gophercloud"
-const path = "users"
+const (
+ tenantPath = "tenants"
+ userPath = "users"
+)
func resourceURL(c *gophercloud.ServiceClient, id string) string {
- return c.ServiceURL(path, id)
+ return c.ServiceURL(userPath, id)
}
func rootURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL(path)
+ return c.ServiceURL(userPath)
+}
+
+func listRolesURL(c *gophercloud.ServiceClient, tenantID, userID string) string {
+ return c.ServiceURL(tenantPath, tenantID, userPath, userID)
}