| package identity | 
 |  | 
 | 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, if successful, yields an unpacked collection of fields related to the user's access credentials, called a "token." | 
 | // 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 | 
 | } |