| Samuel A. Falvo II | 1d3fa66 | 2013-06-25 15:29:32 -0700 | [diff] [blame] | 1 | package gophercloud | 
|  | 2 |  | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 3 | import ( | 
|  | 4 | "github.com/racker/perigee" | 
|  | 5 | ) | 
|  | 6 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 7 | // AuthOptions lets anyone calling Authenticate() supply the required access credentials. | 
|  | 8 | // At present, only Identity V2 API support exists; therefore, only Username, Password, | 
|  | 9 | // and optionally, TenantId are provided.  If future Identity API versions become available, | 
|  | 10 | // alternative fields unique to those versions may appear here. | 
| Samuel A. Falvo II | 1d3fa66 | 2013-06-25 15:29:32 -0700 | [diff] [blame] | 11 | type AuthOptions struct { | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 12 | // Username and Password are required if using Identity V2 API. | 
|  | 13 | // Consult with your provider's control panel to discover your | 
|  | 14 | // account's username and password. | 
|  | 15 | Username, Password string | 
|  | 16 |  | 
|  | 17 | // The TenantId field is optional for the Identity V2 API. | 
|  | 18 | TenantId string | 
| Samuel A. Falvo II | 1d3fa66 | 2013-06-25 15:29:32 -0700 | [diff] [blame] | 19 | } | 
|  | 20 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 21 | // AuthContainer provides a JSON encoding wrapper for passing credentials to the Identity | 
|  | 22 | // service.  You will not work with this structure directly. | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 23 | type AuthContainer struct { | 
|  | 24 | Auth Auth `json:"auth"` | 
|  | 25 | } | 
|  | 26 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 27 | // Auth provides a JSON encoding wrapper for passing credentials to the Identity | 
|  | 28 | // service.  You will not work with this structure directly. | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 29 | type Auth struct { | 
|  | 30 | PasswordCredentials PasswordCredentials `json:"passwordCredentials"` | 
| Samuel A. Falvo II | 839428e | 2013-06-25 18:02:24 -0700 | [diff] [blame] | 31 | TenantId            string              `json:"tenantId,omitempty"` | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 32 | } | 
|  | 33 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 34 | // PasswordCredentials provides a JSON encoding wrapper for passing credentials to the Identity | 
|  | 35 | // service.  You will not work with this structure directly. | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 36 | type PasswordCredentials struct { | 
|  | 37 | Username string `json:"username"` | 
|  | 38 | Password string `json:"password"` | 
|  | 39 | } | 
|  | 40 |  | 
| Samuel A. Falvo II | d1ee798 | 2013-06-26 14:32:45 -0700 | [diff] [blame] | 41 | // Access encapsulates the API token and its relevant fields, as well as the | 
|  | 42 | // services catalog that Identity API returns once authenticated.  You'll probably | 
|  | 43 | // rarely use this record directly, unless you intend on marshalling or unmarshalling | 
|  | 44 | // Identity API JSON records yourself. | 
|  | 45 | type Access struct { | 
|  | 46 | Token          Token | 
|  | 47 | ServiceCatalog []CatalogEntry | 
|  | 48 | User           User | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 49 | } | 
|  | 50 |  | 
| Samuel A. Falvo II | d1ee798 | 2013-06-26 14:32:45 -0700 | [diff] [blame] | 51 | // Token encapsulates an authentication token and when it expires.  It also includes | 
|  | 52 | // tenant information if available. | 
|  | 53 | type Token struct { | 
|  | 54 | Id, Expires string | 
|  | 55 | Tenant      Tenant | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | // Tenant encapsulates tenant authentication information.  If, after authentication, | 
|  | 59 | // no tenant information is supplied, both Id and Name will be "". | 
|  | 60 | type Tenant struct { | 
|  | 61 | Id, Name string | 
|  | 62 | } | 
|  | 63 |  | 
|  | 64 | // User encapsulates the user credentials, and provides visibility in what | 
|  | 65 | // the user can do through its role assignments. | 
|  | 66 | type User struct { | 
|  | 67 | Id, Name          string | 
|  | 68 | XRaxDefaultRegion string `json:"RAX-AUTH:defaultRegion"` | 
|  | 69 | Roles             []Role | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | // Role encapsulates a permission that a user can rely on. | 
|  | 73 | type Role struct { | 
|  | 74 | Description, Id, Name string | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | // CatalogEntry encapsulates a service catalog record. | 
|  | 78 | type CatalogEntry struct { | 
|  | 79 | Name, Type string | 
|  | 80 | Endpoints  []EntryEndpoint | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | // EntryEndpoint encapsulates how to get to the API of some service. | 
|  | 84 | type EntryEndpoint struct { | 
|  | 85 | Region, TenantId                    string | 
|  | 86 | PublicURL, InternalURL              string | 
|  | 87 | VersionId, VersionInfo, VersionList string | 
|  | 88 | } | 
|  | 89 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 90 | // Authenticate() grants access to the OpenStack-compatible provider API. | 
|  | 91 | // | 
|  | 92 | // Providers are identified through a unique key string. | 
|  | 93 | // See the RegisterProvider() method for more details. | 
|  | 94 | // | 
|  | 95 | // The supplied AuthOptions instance allows the client to specify only those credentials | 
|  | 96 | // relevant for the authentication request.  At present, support exists for OpenStack | 
|  | 97 | // Identity V2 API only; support for V3 will become available as soon as documentation for it | 
|  | 98 | // becomes readily available. | 
|  | 99 | // | 
|  | 100 | // For Identity V2 API requirements, you must provide at least the Username and Password | 
|  | 101 | // options.  The TenantId field is optional, and defaults to "". | 
| Samuel A. Falvo II | d1ee798 | 2013-06-26 14:32:45 -0700 | [diff] [blame] | 102 | func (c *Context) Authenticate(provider string, options AuthOptions) (*Access, error) { | 
|  | 103 | var access *Access | 
|  | 104 |  | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 105 | p, err := c.ProviderByName(provider) | 
| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 106 | if err != nil { | 
|  | 107 | return nil, err | 
|  | 108 | } | 
| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 109 | if (options.Username == "") || (options.Password == "") { | 
|  | 110 | return nil, ErrCredentials | 
|  | 111 | } | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 112 |  | 
|  | 113 | err = perigee.Post(p.AuthEndpoint, perigee.Options{ | 
|  | 114 | CustomClient: c.httpClient, | 
| Samuel A. Falvo II | 839428e | 2013-06-25 18:02:24 -0700 | [diff] [blame] | 115 | ReqBody: &AuthContainer{ | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 116 | Auth: Auth{ | 
|  | 117 | PasswordCredentials: PasswordCredentials{ | 
|  | 118 | Username: options.Username, | 
|  | 119 | Password: options.Password, | 
|  | 120 | }, | 
|  | 121 | TenantId: options.TenantId, | 
|  | 122 | }, | 
|  | 123 | }, | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 124 | Results: &struct { | 
| Samuel A. Falvo II | d1ee798 | 2013-06-26 14:32:45 -0700 | [diff] [blame] | 125 | Access **Access `json:"access"` | 
|  | 126 | }{ | 
|  | 127 | &access, | 
|  | 128 | }, | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 129 | }) | 
| Samuel A. Falvo II | d1ee798 | 2013-06-26 14:32:45 -0700 | [diff] [blame] | 130 | return access, err | 
| Samuel A. Falvo II | 1d3fa66 | 2013-06-25 15:29:32 -0700 | [diff] [blame] | 131 | } |