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)
 }