func newClientManager(c *config.Config) client.Manager { ctx := c.Context() switch con := ctx.Connection.(type) { case *config.MemoryConnection: return &client.MemoryManager{ Clients: map[string]*fosite.DefaultClient{}, Hasher: ctx.Hasher, } case *config.RethinkDBConnection: con.CreateTableIfNotExists("hydra_clients") m := &client.RethinkManager{ Session: con.GetSession(), Table: r.Table("hydra_clients"), Hasher: ctx.Hasher, } if err := m.ColdStart(); err != nil { logrus.Fatalf("Could not fetch initial state: %s", err) } m.Watch(context.Background()) return m default: panic("Unknown connection type.") } }
func newConnectionHandler(c *config.Config, router *httprouter.Router) *connection.Handler { ctx := c.Context() h := &connection.Handler{} h.H = &herodot.JSON{} h.W = ctx.Warden h.SetRoutes(router) switch con := ctx.Connection.(type) { case *config.MemoryConnection: h.Manager = connection.NewMemoryManager() break case *config.RethinkDBConnection: con.CreateTableIfNotExists("hydra_policies") m := &connection.RethinkManager{ Session: con.GetSession(), Table: r.Table("hydra_policies"), } if err := m.ColdStart(); err != nil { logrus.Fatalf("Could not fetch initial state: %s", err) } m.Watch(context.Background()) h.Manager = m break default: panic("Unknown connection type.") } return h }
func (h *Handler) Start(c *config.Config, router *httprouter.Router) { ctx := c.Context() // Set up warden clientsManager := newClientManager(c) injectFositeStore(c, clientsManager) ctx.Warden = &warden.LocalWarden{ Warden: &ladon.Ladon{ Manager: ctx.LadonManager, }, TokenValidator: &core.CoreValidator{ AccessTokenStrategy: ctx.FositeStrategy, AccessTokenStorage: ctx.FositeStore, }, Issuer: c.Issuer, } // Set up handlers h.Clients = newClientHandler(c, router, clientsManager) h.Keys = newJWKHandler(c, router) h.Connections = newConnectionHandler(c, router) h.Policy = newPolicyHandler(c, router) h.OAuth2 = newOAuth2Handler(c, router, h.Keys.Manager) // Create root account if new install h.createRS256KeysIfNotExist(c, oauth2.ConsentEndpointKey, "private") h.createRS256KeysIfNotExist(c, oauth2.ConsentChallengeKey, "private") h.createRootIfNewInstall(c) }
func newJWKHandler(c *config.Config, router *httprouter.Router) *jwk.Handler { ctx := c.Context() h := &jwk.Handler{ H: &herodot.JSON{}, W: ctx.Warden, } h.SetRoutes(router) switch con := ctx.Connection.(type) { case *config.MemoryConnection: ctx.KeyManager = &jwk.MemoryManager{} break case *config.RethinkDBConnection: con.CreateTableIfNotExists("hydra_json_web_keys") m := &jwk.RethinkManager{ Session: con.GetSession(), Keys: map[string]jose.JsonWebKeySet{}, Table: r.Table("hydra_json_web_keys"), Cipher: &jwk.AEAD{ Key: c.GetSystemSecret(), }, } if err := m.ColdStart(); err != nil { logrus.Fatalf("Could not fetch initial state: %s", err) } m.Watch(context.Background()) ctx.KeyManager = m break default: logrus.Fatalf("Unknown connection type.") } h.Manager = ctx.KeyManager return h }
func newClientHandler(c *config.Config, router *httprouter.Router, manager client.Manager) *client.Handler { ctx := c.Context() h := &client.Handler{ H: &herodot.JSON{}, W: ctx.Warden, Manager: manager, } h.SetRoutes(router) return h }
func newPolicyHandler(c *config.Config, router *httprouter.Router) *policy.Handler { ctx := c.Context() h := &policy.Handler{ H: &herodot.JSON{}, W: ctx.Warden, Manager: ctx.LadonManager, } h.SetRoutes(router) return h }
func NewHandler(c *config.Config, router *httprouter.Router) *WardenHandler { ctx := c.Context() h := &WardenHandler{ H: &herodot.JSON{}, Warden: ctx.Warden, Ladon: &ladon.Ladon{ Manager: ctx.LadonManager, }, } h.SetRoutes(router) return h }
func (h *Handler) createRS256KeysIfNotExist(c *config.Config, set, lookup string) { ctx := c.Context() generator := jwk.RS256Generator{} if _, err := ctx.KeyManager.GetKey(set, lookup); errors.Is(err, pkg.ErrNotFound) { logrus.Warnf("Key pair for signing %s is missing. Creating new one.", set) keys, err := generator.Generate("") pkg.Must(err, "Could not generate %s key: %s", set, err) err = ctx.KeyManager.AddKeySet(set, keys) pkg.Must(err, "Could not persist %s key: %s", set, err) } }
func (h *Handler) createRootIfNewInstall(c *config.Config) { ctx := c.Context() clients, err := h.Clients.Manager.GetClients() pkg.Must(err, "Could not fetch client list: %s", err) if len(clients) != 0 { return } rs, err := pkg.GenerateSecret(16) pkg.Must(err, "Could notgenerate secret because %s", err) secret := []byte(string(rs)) logrus.Warn("No clients were found. Creating a temporary root client...") root := &fosite.DefaultClient{ Name: "This temporary client is generated by hydra and is granted all of hydra's administrative privileges. It must be removed when everything is set up.", GrantTypes: []string{"client_credentials", "authorization_code"}, ResponseTypes: []string{"token", "code"}, GrantedScopes: []string{"hydra", "core"}, RedirectURIs: []string{"http://localhost:4445/callback"}, Secret: secret, } err = h.Clients.Manager.CreateClient(root) pkg.Must(err, "Could not create temporary root because %s", err) err = ctx.LadonManager.Create(&ladon.DefaultPolicy{ Description: "This is a policy created by hydra and issued to the first client. It grants all of hydra's administrative privileges to the client and enables the client_credentials response type.", Subjects: []string{root.GetID()}, Effect: ladon.AllowAccess, Resources: []string{"rn:hydra:<.*>"}, Actions: []string{"<.*>"}, }) pkg.Must(err, "Could not create admin policy because %s", err) c.Lock() c.ClientID = root.ID c.ClientSecret = string(secret) c.Unlock() logrus.Warn("Temporary root client created.") logrus.Warnf("client_id: %s", root.GetID()) logrus.Warnf("client_secret: %s", string(secret)) logrus.Warn("The root client must be removed in production. The root's credentials could be accidentally logged.") }