blob: dbd367ef3ad79b80897b1fc8e1411f091690ed1c [file] [log] [blame]
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -08001package identity
2
3import (
4 "github.com/racker/perigee"
5)
6
Samuel A. Falvo II2b963212014-02-09 02:12:30 -08007// AuthResults encapsulates the raw results from an authentication request.
8// As OpenStack allows extensions to influence the structure returned in
9// ways that Gophercloud cannot predict at compile-time, you should use
10// type-safe accessors to work with the data represented by this type,
11// such as ServiceCatalog() and Token().
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080012type AuthResults map[string]interface{}
13
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080014// AuthOptions lets anyone calling Authenticate() supply the required access
15// credentials. At present, only Identity V2 API support exists; therefore,
16// only Username, Password, and optionally, TenantId are provided. If future
17// Identity API versions become available, alternative fields unique to those
18// versions may appear here.
19//
20// Endpoint specifies the HTTP endpoint offering the Identity V2 API.
21// Required.
22//
23// Username is required if using Identity V2 API. Consult with your provider's
24// control panel to discover your account's username.
25//
26// At most one of Password or ApiKey is required if using Identity V2 API.
27// Consult with your provider's control panel to discover your account's
28// preferred method of authentication.
29//
30// The TenantId and TenantName fields are optional for the Identity V2 API.
31// Some providers allow you to specify a TenantName instead of the TenantId.
32// Some require both. Your provider's authentication policies will determine
33// how these fields influence authentication.
34//
35// AllowReauth should be set to true if you grant permission for Gophercloud to
36// cache your credentials in memory, and to allow Gophercloud to attempt to
37// re-authenticate automatically if/when your token expires. If you set it to
38// false, it will not cache these settings, but re-authentication will not be
39// possible. This setting defaults to false.
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080040type AuthOptions struct {
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080041 Endpoint string
42 Username string
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080043 Password, ApiKey string
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080044 TenantId string
45 TenantName string
46 AllowReauth bool
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080047}
48
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080049// Authenticate passes the supplied credentials to the OpenStack provider for authentication.
50// If successful, the caller may use Token() to retrieve the authentication token,
51// and ServiceCatalog() to retrieve the set of services available to the API user.
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080052func Authenticate(options AuthOptions) (AuthResults, error) {
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080053 type AuthContainer struct {
54 Auth auth `json:"auth"`
55 }
56
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080057 var ar AuthResults
58
59 if options.Endpoint == "" {
60 return nil, ErrEndpoint
61 }
62
63 if (options.Username == "") || (options.Password == "" && options.ApiKey == "") {
64 return nil, ErrCredentials
65 }
66
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080067 url := options.Endpoint + "/tokens"
68 err := perigee.Post(url, perigee.Options{
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080069 ReqBody: &AuthContainer{
70 Auth: getAuthCredentials(options),
71 },
72 Results: &ar,
73 })
74 return ar, err
75}
76
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080077func getAuthCredentials(options AuthOptions) auth {
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080078 if options.ApiKey == "" {
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080079 return auth{
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080080 PasswordCredentials: &struct {
81 Username string `json:"username"`
82 Password string `json:"password"`
83 }{
84 Username: options.Username,
85 Password: options.Password,
86 },
87 TenantId: options.TenantId,
88 TenantName: options.TenantName,
89 }
90 } else {
Samuel A. Falvo II2b963212014-02-09 02:12:30 -080091 return auth{
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -080092 ApiKeyCredentials: &struct {
93 Username string `json:"username"`
94 ApiKey string `json:"apiKey"`
95 }{
96 Username: options.Username,
97 ApiKey: options.ApiKey,
98 },
99 TenantId: options.TenantId,
100 TenantName: options.TenantName,
101 }
102 }
103}
104
Samuel A. Falvo II2b963212014-02-09 02:12:30 -0800105type auth struct {
Samuel A. Falvo II8a549ef2014-01-24 15:20:54 -0800106 PasswordCredentials interface{} `json:"passwordCredentials,omitempty"`
107 ApiKeyCredentials interface{} `json:"RAX-KSKEY:apiKeyCredentials,omitempty"`
108 TenantId string `json:"tenantId,omitempty"`
109 TenantName string `json:"tenantName,omitempty"`
110}
Samuel A. Falvo II2b963212014-02-09 02:12:30 -0800111
112func GetExtensions(options AuthOptions) (ExtensionsResult, error) {
113 var exts ExtensionsResult
114
115 url := options.Endpoint + "/extensions"
116 err := perigee.Get(url, perigee.Options{
117 Results: &exts,
118 })
119 return exts, err
120}