dex/connector/connector_local.go
Eric Chiang ac73d3cdf2 *: load password infos from users file in no-db mode not connectors
In --no-db mode, load passwords from the users file instead of the
connectors file. This allows us to remove the password infos field
from the local connector and stop loading them during connector
registration, a case that was causing panics when using a real
database (see #286).

Fixes #286
Closes #340
2016-04-06 11:15:05 -07:00

120 lines
2.4 KiB
Go

package connector
import (
"fmt"
"html/template"
"net/http"
"net/url"
"path"
"github.com/coreos/dex/user"
"github.com/coreos/go-oidc/oidc"
)
const (
LocalConnectorType = "local"
LoginPageTemplateName = "local-login.html"
)
func init() {
RegisterConnectorConfigType(LocalConnectorType, func() ConnectorConfig { return &LocalConnectorConfig{} })
}
type LocalConnectorConfig struct {
ID string `json:"id"`
}
func (cfg *LocalConnectorConfig) ConnectorID() string {
return cfg.ID
}
func (cfg *LocalConnectorConfig) ConnectorType() string {
return LocalConnectorType
}
func (cfg *LocalConnectorConfig) Connector(ns url.URL, lf oidc.LoginFunc, tpls *template.Template) (Connector, error) {
tpl := tpls.Lookup(LoginPageTemplateName)
if tpl == nil {
return nil, fmt.Errorf("unable to find necessary HTML template")
}
idpc := &LocalConnector{
id: cfg.ID,
namespace: ns,
loginFunc: lf,
loginTpl: tpl,
}
return idpc, nil
}
type LocalConnector struct {
id string
idp *LocalIdentityProvider
namespace url.URL
loginFunc oidc.LoginFunc
loginTpl *template.Template
}
type Page struct {
PostURL string
Name string
Error bool
Message string
SessionKey string
}
func (c *LocalConnector) ID() string {
return c.id
}
func (c *LocalConnector) Healthy() error {
return nil
}
func (c *LocalConnector) SetLocalIdentityProvider(idp *LocalIdentityProvider) {
c.idp = idp
}
func (c *LocalConnector) LoginURL(sessionKey, prompt string) (string, error) {
q := url.Values{}
q.Set("session_key", sessionKey)
q.Set("prompt", prompt)
enc := q.Encode()
return path.Join(c.namespace.Path, "login") + "?" + enc, nil
}
func (c *LocalConnector) Register(mux *http.ServeMux, errorURL url.URL) {
route := c.namespace.Path + "/login"
mux.Handle(route, handleLoginFunc(c.loginFunc, c.loginTpl, c.idp, route, errorURL))
}
func (c *LocalConnector) Sync() chan struct{} {
return make(chan struct{})
}
func (c *LocalConnector) TrustedEmailProvider() bool {
return false
}
type LocalIdentityProvider struct {
PasswordInfoRepo user.PasswordInfoRepo
UserRepo user.UserRepo
}
func (m *LocalIdentityProvider) Identity(email, password string) (*oidc.Identity, error) {
user, err := m.UserRepo.GetByEmail(nil, email)
if err != nil {
return nil, err
}
id := user.ID
pi, err := m.PasswordInfoRepo.Get(nil, id)
if err != nil {
return nil, err
}
return pi.Authenticate(password)
}