Includes AuthOpts struct and AuthRef interface, plus an Identity v2 password auth implementation. Note: the examples work, the objectstore_test is broken, will be fixed along with additional session and auth tests. Change-Id: I77b07c92586c37e855b466e18dea133a4a938aaachanges/36/175236/3
parent
ef7386d2c4
commit
9de84b3c5d
@ -0,0 +1,81 @@
|
||||
// auth-password - Username/Password Authentication
|
||||
// Copyright 2015 Dean Troyer
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
// The token request structure for Identity v2
|
||||
|
||||
type PasswordCredentials struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type OSAuth struct {
|
||||
PasswordCredentials `json:"passwordCredentials"`
|
||||
Project string `json:"tenantName"`
|
||||
}
|
||||
|
||||
type UserPassV2 struct {
|
||||
OSAuth `json:"auth"`
|
||||
AuthUrl string `json:"-"`
|
||||
}
|
||||
|
||||
func NewUserPassV2(ao AuthOpts) (upv2 *UserPassV2, err error) {
|
||||
// Validate incoming values
|
||||
if ao.AuthUrl == "" {
|
||||
err = errors.New("AuthUrl required")
|
||||
return nil, err
|
||||
}
|
||||
if ao.Username == "" {
|
||||
err = errors.New("Username required")
|
||||
return nil, err
|
||||
}
|
||||
if ao.Password == "" {
|
||||
err = errors.New("Password required")
|
||||
return nil, err
|
||||
}
|
||||
upv2 = &UserPassV2{
|
||||
AuthUrl: ao.AuthUrl,
|
||||
OSAuth: OSAuth{
|
||||
PasswordCredentials: PasswordCredentials{
|
||||
Username: ao.Username,
|
||||
Password: ao.Password,
|
||||
},
|
||||
Project: ao.Project,
|
||||
},
|
||||
}
|
||||
return upv2, nil
|
||||
}
|
||||
|
||||
// Produce JSON output
|
||||
func (s *UserPassV2) JSON() []byte {
|
||||
reqAuth, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
// Return an empty structure
|
||||
reqAuth = []byte{'{', '}'}
|
||||
}
|
||||
return reqAuth
|
||||
}
|
||||
|
||||
// func (self *UserPassV2) AuthUserPassV2(opts interface{}) (AuthRef, error) {
|
||||
// auth, err := self.GetAuthRef()
|
||||
// return AuthRef(auth), err
|
||||
// }
|
@ -0,0 +1,81 @@
|
||||
// auth-token - Token Authentication
|
||||
// Copyright 2015 Dean Troyer
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Identity Response Types
|
||||
|
||||
type AccessType struct {
|
||||
Token Token `json:"token"`
|
||||
User interface{} `json:"id"`
|
||||
ServiceCatalog []ServiceCatalogEntry `json:"servicecatalog"`
|
||||
}
|
||||
|
||||
type AuthToken struct {
|
||||
Access AccessType `json:"access"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
ID string `json:"id"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Project struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"tenant"`
|
||||
}
|
||||
|
||||
type ServiceCatalogEntry struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Endpoints []ServiceEndpoint `json:"endpoints"`
|
||||
// Endpoints []map[string]string `json:"endpoints"`
|
||||
}
|
||||
|
||||
type ServiceEndpoint struct {
|
||||
Type string `json:"type"`
|
||||
Region string `json:"region"`
|
||||
PublicURL string `json:"publicurl"`
|
||||
AdminURL string `json:"adminurl"`
|
||||
InternalURL string `json:"internalurl"`
|
||||
VersionID string `json:"versionid"`
|
||||
}
|
||||
|
||||
func (s AuthToken) GetToken() string {
|
||||
return s.Access.Token.ID
|
||||
}
|
||||
|
||||
func (s AuthToken) GetExpiration() time.Time {
|
||||
return s.Access.Token.Expires
|
||||
}
|
||||
|
||||
func (s AuthToken) GetEndpoint(serviceType string, regionName string) (string, error) {
|
||||
|
||||
// Parse service catalog
|
||||
for _, v := range s.Access.ServiceCatalog {
|
||||
if v.Type == serviceType {
|
||||
for _, r := range v.Endpoints {
|
||||
if regionName == "" || r.Region == regionName {
|
||||
return r.PublicURL, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", errors.New("err: endpoint not found")
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
// auth - Authentication interface
|
||||
// Copyright 2015 Dean Troyer
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AuthRef is the returned authentication object, maybe v2 or v3
|
||||
type AuthRef interface {
|
||||
GetToken() string
|
||||
GetExpiration() time.Time
|
||||
GetEndpoint(string, string) (string, error)
|
||||
}
|
||||
|
||||
// AuthOpts is the set of credentials used to authenticate to OpenStack
|
||||
type AuthOpts struct {
|
||||
// AuthUrl is always required
|
||||
AuthUrl string
|
||||
|
||||
// Domain is ignored for v2 and required for v3 auth
|
||||
Domain string
|
||||
|
||||
// Project is optional to get an unscoped token but required for
|
||||
// a scoped token, which is required to do pretty much everything
|
||||
// except list projects
|
||||
Project string
|
||||
|
||||
// Username is required for password auth
|
||||
Username string
|
||||
|
||||
// Password is required for password auth
|
||||
Password string
|
||||
|
||||
// Token is required for Toekn auth
|
||||
Token string
|
||||
}
|
||||
|
||||
func (s *AuthOpts) GetAuthType() (string, error) {
|
||||
var auth_type string
|
||||
if s.AuthUrl != "" && s.Token != "" {
|
||||
auth_type = "token"
|
||||
} else if s.Username != "" {
|
||||
auth_type = "password"
|
||||
}
|
||||
return auth_type, nil
|
||||
}
|
||||
|
||||
// Basic auth call
|
||||
// These args should be an interface??
|
||||
func DoAuthRequest(authopts AuthOpts) (AuthRef, error) {
|
||||
// url string, body []byte)
|
||||
var auth = AuthToken{}
|
||||
|
||||
auth_mod, err := NewUserPassV2(authopts)
|
||||
if err != nil {
|
||||
err = errors.New("Failed to get auth options")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
path := auth_mod.AuthUrl + "/tokens"
|
||||
body := auth_mod.JSON()
|
||||
resp, err := Post(path, nil, nil, &body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contentType := strings.ToLower(resp.Header.Get("Content-Type"))
|
||||
if strings.Contains(contentType, "json") != true {
|
||||
return nil, errors.New("err: header Content-Type is not JSON")
|
||||
}
|
||||
|
||||
rbody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, errors.New("aaa")
|
||||
}
|
||||
if err = json.Unmarshal(rbody, &auth); err != nil {
|
||||
return nil, errors.New("bbb")
|
||||
}
|
||||
|
||||
return auth, nil
|
||||
}
|
Loading…
Reference in new issue