blob: 0012a17a009f9ac9693e3e1ae00b45a8eb4253e2 [file] [log] [blame]
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -08001package identity
2
3import (
4 "github.com/racker/perigee"
5)
6
7type 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.
13type 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
42func 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
62func 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.
92type 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.
98type 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}