keystone: squashed changes from knangia/dex
This commit is contained in:
		| @@ -11,15 +11,12 @@ FROM alpine:3.8 | |||||||
| # experience when this doesn't work out of the box. | # experience when this doesn't work out of the box. | ||||||
| # | # | ||||||
| # OpenSSL is required so wget can query HTTPS endpoints for health checking. | # OpenSSL is required so wget can query HTTPS endpoints for health checking. | ||||||
| RUN apk add --update ca-certificates openssl | RUN apk add --update ca-certificates openssl bash | ||||||
|  |  | ||||||
| COPY --from=0 /go/bin/dex /usr/local/bin/dex |  | ||||||
|  |  | ||||||
| # Import frontend assets and set the correct CWD directory so the assets | # Import frontend assets and set the correct CWD directory so the assets | ||||||
| # are in the default path. | # are in the default path. | ||||||
| COPY web /web | COPY web /web | ||||||
| WORKDIR / | WORKDIR / | ||||||
|  |  | ||||||
| ENTRYPOINT ["dex"] | EXPOSE 5500-5600 | ||||||
|  | CMD ["bash"] | ||||||
| CMD ["version"] |  | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ type Identity struct { | |||||||
| 	// | 	// | ||||||
| 	// This data is never shared with end users, OAuth clients, or through the API. | 	// This data is never shared with end users, OAuth clients, or through the API. | ||||||
| 	ConnectorData []byte | 	ConnectorData []byte | ||||||
|  | 	Password string | ||||||
| } | } | ||||||
|  |  | ||||||
| // PasswordConnector is an interface implemented by connectors which take a | // PasswordConnector is an interface implemented by connectors which take a | ||||||
|   | |||||||
							
								
								
									
										120
									
								
								connector/keystone/keystone.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								connector/keystone/keystone.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | |||||||
|  | // Package keystone provides authentication strategy using Keystone. | ||||||
|  | package keystone | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"github.com/dexidp/dex/connector" | ||||||
|  | 	"github.com/sirupsen/logrus" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"net/http" | ||||||
|  | 	"bytes" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"log" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type KeystoneConnector struct { | ||||||
|  | 	domain string | ||||||
|  | 	keystoneURI string | ||||||
|  | 	Logger   logrus.FieldLogger | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	_ connector.PasswordConnector = &KeystoneConnector{} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Config holds the configuration parameters for Keystone connector. | ||||||
|  | // An example config: | ||||||
|  | //	connectors: | ||||||
|  | //		type: ksconfig | ||||||
|  | //		id: keystone | ||||||
|  | //		name: Keystone | ||||||
|  | //		config: | ||||||
|  | //			keystoneURI: http://example:5000/v3/auth/tokens | ||||||
|  | //			domain: default | ||||||
|  |  | ||||||
|  | type Config struct { | ||||||
|  | 	Domain string `json:"domain"` | ||||||
|  | 	KeystoneURI string `json:"keystoneURI"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Open returns an authentication strategy using Keystone. | ||||||
|  | func (c *Config) Open(id string, logger logrus.FieldLogger) (connector.Connector, error) { | ||||||
|  | 	return &KeystoneConnector{c.Domain,c.KeystoneURI,logger}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p KeystoneConnector) Close() error { return nil } | ||||||
|  |  | ||||||
|  | // Declare KeystoneJson struct to get a token | ||||||
|  | type KeystoneJson struct { | ||||||
|  | 	Auth `json:"auth"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type Auth struct { | ||||||
|  | 	Identity `json:"identity"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type Identity struct { | ||||||
|  | 	Methods  []string `json:"methods"` | ||||||
|  | 	Password `json:"password"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type Password struct { | ||||||
|  | 	User `json:"user"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type User struct { | ||||||
|  | 	Name   string `json:"name"` | ||||||
|  | 	Domain `json:"domain"` | ||||||
|  | 	Password string `json:"password"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type Domain struct { | ||||||
|  | 	ID string `json:"id"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p KeystoneConnector) Login(ctx context.Context, s connector.Scopes, username, password string) (identity connector.Identity, validPassword bool, err error) { | ||||||
|  | 	// Instantiate KeystoneJson struct type to get a token | ||||||
|  | 	jsonData := KeystoneJson{ | ||||||
|  | 		Auth: Auth{ | ||||||
|  | 			Identity: Identity{ | ||||||
|  | 				Methods:[]string{"password"}, | ||||||
|  | 				Password: Password{ | ||||||
|  | 					User: User{ | ||||||
|  | 						Name: username, | ||||||
|  | 						Domain: Domain{ID:p.domain}, | ||||||
|  | 						Password: password, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Marshal jsonData | ||||||
|  | 	jsonValue, _ := json.Marshal(jsonData) | ||||||
|  |  | ||||||
|  | 	// Make an http post request to Keystone URI | ||||||
|  | 	response, err := http.Post(p.keystoneURI, "application/json", bytes.NewBuffer(jsonValue)) | ||||||
|  |  | ||||||
|  | 	// Providing wrong password or wrong keystone URI throws error | ||||||
|  | 	if err == nil && response.StatusCode == 201 { | ||||||
|  | 		data, _ := ioutil.ReadAll(response.Body) | ||||||
|  | 		fmt.Println(string(data)) | ||||||
|  | 		identity.Username =	username | ||||||
|  | 		return identity, true, nil | ||||||
|  |  | ||||||
|  | 	} else if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 		return identity, false, err | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  | 		fmt.Printf("The HTTP request failed with error %v\n", response.StatusCode) | ||||||
|  | 		data, _ := ioutil.ReadAll(response.Body) | ||||||
|  | 		fmt.Println(string(data)) | ||||||
|  | 		return identity, false, err | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	return identity, false, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p KeystoneConnector) Prompt() string { return "username" } | ||||||
							
								
								
									
										44
									
								
								examples/config-keystone.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								examples/config-keystone.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | # The base path of dex and the external name of the OpenID Connect service. | ||||||
|  | # This is the canonical URL that all clients MUST use to refer to dex. If a | ||||||
|  | # path is provided, dex's HTTP service will listen at a non-root URL. | ||||||
|  | issuer: http://0.0.0.0:5556/dex | ||||||
|  |  | ||||||
|  | # The storage configuration determines where dex stores its state. Supported | ||||||
|  | # options include SQL flavors and Kubernetes third party resources. | ||||||
|  | # | ||||||
|  | # See the storage document at Documentation/storage.md for further information. | ||||||
|  | storage: | ||||||
|  |   type: sqlite3 | ||||||
|  |   config: | ||||||
|  |     file: examples/dex.db   #be in the dex directory, else change path here | ||||||
|  |  | ||||||
|  | # Configuration for the HTTP endpoints. | ||||||
|  | web: | ||||||
|  |   http: 0.0.0.0:5556 | ||||||
|  |  | ||||||
|  | # Configuration for telemetry | ||||||
|  | telemetry: | ||||||
|  |   http: 0.0.0.0:5558 | ||||||
|  |  | ||||||
|  | oauth2: | ||||||
|  |   responseTypes: ["id_token"] | ||||||
|  |  | ||||||
|  | # Instead of reading from an external storage, use this list of clients. | ||||||
|  | staticClients: | ||||||
|  | - id: example-app | ||||||
|  |   redirectURIs: | ||||||
|  |   - 'http://127.0.0.1:5555/callback' | ||||||
|  |   name: 'Example App' | ||||||
|  |   secret: ZXhhbXBsZS1hcHAtc2VjcmV0 | ||||||
|  |  | ||||||
|  | #Provide Keystone connector and its config here | ||||||
|  | connectors: | ||||||
|  | - type: ksconfig | ||||||
|  |   id: keystone | ||||||
|  |   name: Keystone | ||||||
|  |   config: | ||||||
|  |     keystoneURI: http://example:5000/v3/auth/tokens | ||||||
|  |     domain: default | ||||||
|  |  | ||||||
|  | # Let dex keep a list of passwords which can be used to login to dex. | ||||||
|  | enablePasswordDB: true | ||||||
| @@ -34,6 +34,7 @@ import ( | |||||||
| 	"github.com/dexidp/dex/connector/oidc" | 	"github.com/dexidp/dex/connector/oidc" | ||||||
| 	"github.com/dexidp/dex/connector/saml" | 	"github.com/dexidp/dex/connector/saml" | ||||||
| 	"github.com/dexidp/dex/storage" | 	"github.com/dexidp/dex/storage" | ||||||
|  |   "github.com/dexidp/dex/connector/keystone" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // LocalConnector is the local passwordDB connector which is an internal | // LocalConnector is the local passwordDB connector which is an internal | ||||||
| @@ -433,6 +434,7 @@ type ConnectorConfig interface { | |||||||
| // ConnectorsConfig variable provides an easy way to return a config struct | // ConnectorsConfig variable provides an easy way to return a config struct | ||||||
| // depending on the connector type. | // depending on the connector type. | ||||||
| var ConnectorsConfig = map[string]func() ConnectorConfig{ | var ConnectorsConfig = map[string]func() ConnectorConfig{ | ||||||
|  | 	"ksconfig":        func() ConnectorConfig { return new(keystone.Config) }, | ||||||
| 	"mockCallback":    func() ConnectorConfig { return new(mock.CallbackConfig) }, | 	"mockCallback":    func() ConnectorConfig { return new(mock.CallbackConfig) }, | ||||||
| 	"mockPassword":    func() ConnectorConfig { return new(mock.PasswordConfig) }, | 	"mockPassword":    func() ConnectorConfig { return new(mock.PasswordConfig) }, | ||||||
| 	"ldap":            func() ConnectorConfig { return new(ldap.Config) }, | 	"ldap":            func() ConnectorConfig { return new(ldap.Config) }, | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ package storage | |||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user