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
}
Exemple #3
0
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)
}
Exemple #4
0
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
}
Exemple #7
0
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
}
Exemple #8
0
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)
	}
}
Exemple #9
0
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.")
}