| package v2 |
| |
| import ( |
| "github.com/mitchellh/mapstructure" |
| ) |
| |
| // Token provides only the most basic information related to an authentication token. |
| // |
| // Id provides the primary means of identifying a user to the OpenStack API. |
| // OpenStack defines this field as an opaque value, so do not depend on its content. |
| // It is safe, however, to compare for equality. |
| // |
| // Expires provides a timestamp in ISO 8601 format, indicating when the authentication token becomes invalid. |
| // After this point in time, future API requests made using this authentication token will respond with errors. |
| // Either the caller will need to reauthenticate manually, or more preferably, the caller should exploit automatic re-authentication. |
| // See the AuthOptions structure for more details. |
| // |
| // TenantId provides the canonical means of identifying a tenant. |
| // As with Id, this field is defined to be opaque, so do not depend on its content. |
| // It is safe, however, to compare for equality. |
| // |
| // TenantName provides a human-readable tenant name corresponding to the TenantId. |
| type Token struct { |
| ID, Expires string |
| TenantID, TenantName string |
| } |
| |
| // GetToken yields an unpacked collection of fields related to the user's access credentials, called a "token", if successful. |
| // See the Token structure for more details. |
| func GetToken(m AuthResults) (*Token, error) { |
| type ( |
| Tenant struct { |
| ID string |
| Name string |
| } |
| |
| TokenDesc struct { |
| ID string `mapstructure:"id"` |
| Expires string `mapstructure:"expires"` |
| Tenant |
| } |
| ) |
| |
| accessMap, err := getSubmap(m, "access") |
| if err != nil { |
| return nil, err |
| } |
| tokenMap, err := getSubmap(accessMap, "token") |
| if err != nil { |
| return nil, err |
| } |
| t := &TokenDesc{} |
| err = mapstructure.Decode(tokenMap, t) |
| if err != nil { |
| return nil, err |
| } |
| td := &Token{ |
| ID: t.ID, |
| Expires: t.Expires, |
| TenantID: t.Tenant.ID, |
| TenantName: t.Tenant.Name, |
| } |
| return td, nil |
| } |
| |
| func getSubmap(m map[string]interface{}, name string) (map[string]interface{}, error) { |
| entry, ok := m[name] |
| if !ok { |
| return nil, ErrNotImplemented |
| } |
| return entry.(map[string]interface{}), nil |
| } |