And all of the rest of the token operations.
Plus tests for each.
diff --git a/openstack/identity/v3/tokens/requests.go b/openstack/identity/v3/tokens/requests.go
index b8f0d76..ab84d81 100644
--- a/openstack/identity/v3/tokens/requests.go
+++ b/openstack/identity/v3/tokens/requests.go
@@ -13,6 +13,12 @@
DomainName string
}
+func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
+ h := c.AuthenticatedHeaders()
+ h["X-Subject-Token"] = subjectToken
+ return h
+}
+
// Create authenticates and either generates a new token, or changes the Scope of an existing token.
func Create(c *gophercloud.ServiceClient, scope *Scope) (gophercloud.AuthResults, error) {
type domainReq struct {
@@ -243,3 +249,45 @@
return &result, nil
}
+
+// Info validates and retrieves information about another token.
+func Info(c *gophercloud.ServiceClient, token string) (*TokenCreateResult, error) {
+ var result TokenCreateResult
+
+ response, err := perigee.Request("GET", getTokenURL(c), perigee.Options{
+ MoreHeaders: subjectTokenHeaders(c, token),
+ Results: &result.response,
+ OkCodes: []int{200, 203},
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ // Extract the token ID from the response, if present.
+ result.tokenID = response.HttpResponse.Header.Get("X-Subject-Token")
+
+ return &result, nil
+}
+
+// Validate determines if a specified token is valid or not.
+func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
+ response, err := perigee.Request("HEAD", getTokenURL(c), perigee.Options{
+ MoreHeaders: subjectTokenHeaders(c, token),
+ OkCodes: []int{204, 404},
+ })
+ if err != nil {
+ return false, err
+ }
+
+ return response.StatusCode == 204, nil
+}
+
+// Revoke immediately makes specified token invalid.
+func Revoke(c *gophercloud.ServiceClient, token string) error {
+ _, err := perigee.Request("DELETE", getTokenURL(c), perigee.Options{
+ MoreHeaders: subjectTokenHeaders(c, token),
+ OkCodes: []int{204},
+ })
+ return err
+}