| package gophercloud | 
 |  | 
 | import ( | 
 | 	"github.com/racker/perigee" | 
 | ) | 
 |  | 
 | // AuthOptions lets anyone calling Authenticate() supply the required access credentials. | 
 | // At present, only Identity V2 API support exists; therefore, only Username, Password, | 
 | // and optionally, TenantId are provided.  If future Identity API versions become available, | 
 | // alternative fields unique to those versions may appear here. | 
 | type AuthOptions struct { | 
 | 	// Username and Password are required if using Identity V2 API. | 
 | 	// Consult with your provider's control panel to discover your | 
 | 	// account's username and password. | 
 | 	Username, Password string | 
 |  | 
 | 	// The TenantId field is optional for the Identity V2 API. | 
 | 	TenantId string | 
 | } | 
 |  | 
 | // AuthContainer provides a JSON encoding wrapper for passing credentials to the Identity | 
 | // service.  You will not work with this structure directly. | 
 | type AuthContainer struct { | 
 | 	Auth Auth `json:"auth"` | 
 | } | 
 |  | 
 | // Auth provides a JSON encoding wrapper for passing credentials to the Identity | 
 | // service.  You will not work with this structure directly. | 
 | type Auth struct { | 
 | 	PasswordCredentials PasswordCredentials `json:"passwordCredentials"` | 
 | 	TenantId            string              `json:"tenantId,omitempty"` | 
 | } | 
 |  | 
 | // PasswordCredentials provides a JSON encoding wrapper for passing credentials to the Identity | 
 | // service.  You will not work with this structure directly. | 
 | type PasswordCredentials struct { | 
 | 	Username string `json:"username"` | 
 | 	Password string `json:"password"` | 
 | } | 
 |  | 
 | // Access encapsulates the API token and its relevant fields, as well as the | 
 | // services catalog that Identity API returns once authenticated. | 
 | type Access struct { | 
 | 	Token          Token | 
 | 	ServiceCatalog []CatalogEntry | 
 | 	User           User | 
 | } | 
 |  | 
 | // Token encapsulates an authentication token and when it expires.  It also includes | 
 | // tenant information if available. | 
 | type Token struct { | 
 | 	Id, Expires string | 
 | 	Tenant      Tenant | 
 | } | 
 |  | 
 | // Tenant encapsulates tenant authentication information.  If, after authentication, | 
 | // no tenant information is supplied, both Id and Name will be "". | 
 | type Tenant struct { | 
 | 	Id, Name string | 
 | } | 
 |  | 
 | // User encapsulates the user credentials, and provides visibility in what | 
 | // the user can do through its role assignments. | 
 | type User struct { | 
 | 	Id, Name          string | 
 | 	XRaxDefaultRegion string `json:"RAX-AUTH:defaultRegion"` | 
 | 	Roles             []Role | 
 | } | 
 |  | 
 | // Role encapsulates a permission that a user can rely on. | 
 | type Role struct { | 
 | 	Description, Id, Name string | 
 | } | 
 |  | 
 | // CatalogEntry encapsulates a service catalog record. | 
 | type CatalogEntry struct { | 
 | 	Name, Type string | 
 | 	Endpoints  []EntryEndpoint | 
 | } | 
 |  | 
 | // EntryEndpoint encapsulates how to get to the API of some service. | 
 | type EntryEndpoint struct { | 
 | 	Region, TenantId                    string | 
 | 	PublicURL, InternalURL              string | 
 | 	VersionId, VersionInfo, VersionList string | 
 | } | 
 |  | 
 | // Authenticate() grants access to the OpenStack-compatible provider API. | 
 | // | 
 | // Providers are identified through a unique key string. | 
 | // See the RegisterProvider() method for more details. | 
 | // | 
 | // The supplied AuthOptions instance allows the client to specify only those credentials | 
 | // relevant for the authentication request.  At present, support exists for OpenStack | 
 | // Identity V2 API only; support for V3 will become available as soon as documentation for it | 
 | // becomes readily available. | 
 | // | 
 | // For Identity V2 API requirements, you must provide at least the Username and Password | 
 | // options.  The TenantId field is optional, and defaults to "". | 
 | func (c *Context) Authenticate(provider string, options AuthOptions) (*Access, error) { | 
 | 	var access *Access | 
 |  | 
 | 	p, err := c.ProviderByName(provider) | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 | 	if (options.Username == "") || (options.Password == "") { | 
 | 		return nil, ErrCredentials | 
 | 	} | 
 |  | 
 | 	err = perigee.Post(p.AuthEndpoint, perigee.Options{ | 
 | 		CustomClient: c.httpClient, | 
 | 		ReqBody: &AuthContainer{ | 
 | 			Auth: Auth{ | 
 | 				PasswordCredentials: PasswordCredentials{ | 
 | 					Username: options.Username, | 
 | 					Password: options.Password, | 
 | 				}, | 
 | 				TenantId: options.TenantId, | 
 | 			}, | 
 | 		}, | 
 | 		Results: &struct { | 
 | 			Access **Access `json:"access"` | 
 | 		}{ | 
 | 			&access, | 
 | 		}, | 
 | 	}) | 
 | 	return access, err | 
 | } | 
 |  | 
 | // See AccessProvider interface definition for details. | 
 | func (a *Access) FirstEndpointUrlByCriteria(ac ApiCriteria) string { | 
 | 	ep := FindFirstEndpointByCriteria(a.ServiceCatalog, ac) | 
 | 	urls := []string{ep.PublicURL, ep.InternalURL} | 
 | 	return urls[ac.UrlChoice] | 
 | } | 
 |  | 
 | // See AccessProvider interface definition for details. | 
 | func (a *Access) AuthToken() string { | 
 | 	return a.Token.Id | 
 | } |