| Samuel A. Falvo II | 8a549ef | 2014-01-24 15:20:54 -0800 | [diff] [blame^] | 1 | package identity | 
|  | 2 |  | 
|  | 3 | import ( | 
|  | 4 | "github.com/racker/perigee" | 
|  | 5 | ) | 
|  | 6 |  | 
|  | 7 | type AuthResults map[string]interface{} | 
|  | 8 |  | 
|  | 9 | // AuthOptions lets anyone calling Authenticate() supply the required access credentials. | 
|  | 10 | // At present, only Identity V2 API support exists; therefore, only Username, Password, | 
|  | 11 | // and optionally, TenantId are provided.  If future Identity API versions become available, | 
|  | 12 | // alternative fields unique to those versions may appear here. | 
|  | 13 | type AuthOptions struct { | 
|  | 14 | // Endpoint specifies the HTTP endpoint offering the Identity V2 API. | 
|  | 15 | // Required. | 
|  | 16 | Endpoint string | 
|  | 17 |  | 
|  | 18 | // Username is required if using Identity V2 API. | 
|  | 19 | // Consult with your provider's control panel to discover your | 
|  | 20 | // account's username. | 
|  | 21 | Username string | 
|  | 22 |  | 
|  | 23 | // At most one of Password or ApiKey is required if using Identity V2 API. | 
|  | 24 | // Consult with your provider's control panel to discover your | 
|  | 25 | // account's preferred method of authentication. | 
|  | 26 | Password, ApiKey string | 
|  | 27 |  | 
|  | 28 | // The TenantId field is optional for the Identity V2 API. | 
|  | 29 | TenantId string | 
|  | 30 |  | 
|  | 31 | // The TenantName can be specified instead of the TenantId | 
|  | 32 | TenantName string | 
|  | 33 |  | 
|  | 34 | // AllowReauth should be set to true if you grant permission for Gophercloud to cache | 
|  | 35 | // your credentials in memory, and to allow Gophercloud to attempt to re-authenticate | 
|  | 36 | // automatically if/when your token expires.  If you set it to false, it will not cache | 
|  | 37 | // these settings, but re-authentication will not be possible.  This setting defaults | 
|  | 38 | // to false. | 
|  | 39 | AllowReauth bool | 
|  | 40 | } | 
|  | 41 |  | 
|  | 42 | func Authenticate(options AuthOptions) (AuthResults, error) { | 
|  | 43 | var ar AuthResults | 
|  | 44 |  | 
|  | 45 | if options.Endpoint == "" { | 
|  | 46 | return nil, ErrEndpoint | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | if (options.Username == "") || (options.Password == "" && options.ApiKey == "") { | 
|  | 50 | return nil, ErrCredentials | 
|  | 51 | } | 
|  | 52 |  | 
|  | 53 | err := perigee.Post(options.Endpoint, perigee.Options{ | 
|  | 54 | ReqBody: &AuthContainer{ | 
|  | 55 | Auth: getAuthCredentials(options), | 
|  | 56 | }, | 
|  | 57 | Results: &ar, | 
|  | 58 | }) | 
|  | 59 | return ar, err | 
|  | 60 | } | 
|  | 61 |  | 
|  | 62 | func getAuthCredentials(options AuthOptions) Auth { | 
|  | 63 | if options.ApiKey == "" { | 
|  | 64 | return Auth{ | 
|  | 65 | PasswordCredentials: &struct { | 
|  | 66 | Username string `json:"username"` | 
|  | 67 | Password string `json:"password"` | 
|  | 68 | }{ | 
|  | 69 | Username: options.Username, | 
|  | 70 | Password: options.Password, | 
|  | 71 | }, | 
|  | 72 | TenantId:   options.TenantId, | 
|  | 73 | TenantName: options.TenantName, | 
|  | 74 | } | 
|  | 75 | } else { | 
|  | 76 | return Auth{ | 
|  | 77 | ApiKeyCredentials: &struct { | 
|  | 78 | Username string `json:"username"` | 
|  | 79 | ApiKey   string `json:"apiKey"` | 
|  | 80 | }{ | 
|  | 81 | Username: options.Username, | 
|  | 82 | ApiKey:   options.ApiKey, | 
|  | 83 | }, | 
|  | 84 | TenantId:   options.TenantId, | 
|  | 85 | TenantName: options.TenantName, | 
|  | 86 | } | 
|  | 87 | } | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | // AuthContainer provides a JSON encoding wrapper for passing credentials to the Identity | 
|  | 91 | // service.  You will not work with this structure directly. | 
|  | 92 | type AuthContainer struct { | 
|  | 93 | Auth Auth `json:"auth"` | 
|  | 94 | } | 
|  | 95 |  | 
|  | 96 | // Auth provides a JSON encoding wrapper for passing credentials to the Identity | 
|  | 97 | // service.  You will not work with this structure directly. | 
|  | 98 | type Auth struct { | 
|  | 99 | PasswordCredentials interface{} `json:"passwordCredentials,omitempty"` | 
|  | 100 | ApiKeyCredentials   interface{} `json:"RAX-KSKEY:apiKeyCredentials,omitempty"` | 
|  | 101 | TenantId            string      `json:"tenantId,omitempty"` | 
|  | 102 | TenantName          string      `json:"tenantName,omitempty"` | 
|  | 103 | } |