first steps

This commit is contained in:
max furman 2021-05-06 17:03:12 -07:00
parent 2f60f20b0b
commit af3cf7dae9
15 changed files with 251 additions and 205 deletions

View file

@ -31,7 +31,7 @@ import (
// Authority implements the Certificate Authority internal interface. // Authority implements the Certificate Authority internal interface.
type Authority struct { type Authority struct {
config *config.Config config *config.Config
mgmtDB *mgmt.DB mgmtDB mgmt.DB
keyManager kms.KeyManager keyManager kms.KeyManager
provisioners *provisioner.Collection provisioners *provisioner.Collection
db db.AuthDB db db.AuthDB
@ -146,20 +146,26 @@ func (a *Authority) init() error {
// Pull AuthConfig from DB. // Pull AuthConfig from DB.
if true { if true {
if len(a.config.AuthConfig.AuthorityID)_== 0 { // Check if AuthConfig already exists
mgmtDB, err := authMgmtNosql.New(a.db.(nosql.DB), mgmt.DefaultAuthorityID) a.mgmtDB, err = authMgmtNosql.New(a.db.(nosql.DB), mgmt.DefaultAuthorityID)
if err != nil { if err != nil {
return err return err
} }
mgmtAuthConfig, err := mgmt.CreateAuthority(context.Background, mgmtDB, WithDefaultAuthorityID) mgmtAuthConfig, err := a.mgmtDB.GetAuthConfig(context.Background(), mgmt.DefaultAuthorityID)
if err != nil {
if k, ok := err.(*mgmt.Error); ok && k.IsType(mgmt.ErrorNotFoundType) {
mgmtAuthConfig, err = mgmt.CreateAuthority(context.Background(), a.mgmtDB, mgmt.WithDefaultAuthorityID)
if err != nil {
return mgmt.WrapErrorISE(err, "error creating authConfig")
}
} else {
return mgmt.WrapErrorISE(err, "error getting authConfig from db")
}
}
a.config.AuthorityConfig, err = mgmtAuthConfig.ToCertificates()
if err != nil { if err != nil {
return err return err
} }
a.config.AuthConfig, err := mgmtAuthConfig.ToCertificates()
if err != nil {
return err
}
}
} }
// Initialize key manager if it has not been set in the options. // Initialize key manager if it has not been set in the options.
@ -394,6 +400,11 @@ func (a *Authority) GetDatabase() db.AuthDB {
return a.db return a.db
} }
// GetMgmtDatabase returns the mgmt database, if one exists.
func (a *Authority) GetMgmtDatabase() mgmt.DB {
return a.mgmtDB
}
// Shutdown safely shuts down any clients, databases, etc. held by the Authority. // Shutdown safely shuts down any clients, databases, etc. held by the Authority.
func (a *Authority) Shutdown() error { func (a *Authority) Shutdown() error {
if err := a.keyManager.Close(); err != nil { if err := a.keyManager.Close(); err != nil {

View file

@ -32,8 +32,13 @@ var (
MaxVersion: 1.2, MaxVersion: 1.2,
Renegotiation: false, Renegotiation: false,
} }
// DefaultBackdate length of time to backdate certificates to avoid
// clock skew validation issues.
DefaultBackdate = time.Minute DefaultBackdate = time.Minute
// DefaultDisableRenewal disables renewals per provisioner.
DefaultDisableRenewal = false DefaultDisableRenewal = false
// DefaultEnableSSHCA enable SSH CA features per provisioner or globally
// for all provisioners.
DefaultEnableSSHCA = false DefaultEnableSSHCA = false
// GlobalProvisionerClaims default claims for the Authority. Can be overriden // GlobalProvisionerClaims default claims for the Authority. Can be overriden
// by provisioner specific claims. // by provisioner specific claims.
@ -153,7 +158,7 @@ func LoadConfiguration(filename string) (*Config, error) {
return nil, errors.Wrapf(err, "error parsing %s", filename) return nil, errors.Wrapf(err, "error parsing %s", filename)
} }
c.init() c.Init()
return &c, nil return &c, nil
} }

View file

@ -58,6 +58,7 @@ func (h *Handler) GetAdmins(w http.ResponseWriter, r *http.Request) {
// CreateAdmin creates a new admin. // CreateAdmin creates a new admin.
func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) { func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
/*
ctx := r.Context() ctx := r.Context()
var body CreateAdminRequest var body CreateAdminRequest
@ -79,10 +80,12 @@ func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
return return
} }
api.JSONStatus(w, adm, http.StatusCreated) api.JSONStatus(w, adm, http.StatusCreated)
*/
} }
// UpdateAdmin updates an existing admin. // UpdateAdmin updates an existing admin.
func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) { func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
/*
ctx := r.Context() ctx := r.Context()
id := chi.URLParam(r, "id") id := chi.URLParam(r, "id")
@ -109,4 +112,5 @@ func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
return return
} }
api.JSON(w, adm) api.JSON(w, adm)
*/
} }

View file

@ -5,15 +5,14 @@ import (
"github.com/go-chi/chi" "github.com/go-chi/chi"
"github.com/smallstep/certificates/api" "github.com/smallstep/certificates/api"
"github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/config" "github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/mgmt"
) )
// CreateAuthConfigRequest represents the body for a CreateAuthConfig request. // CreateAuthConfigRequest represents the body for a CreateAuthConfig request.
type CreateAuthConfigRequest struct { type CreateAuthConfigRequest struct {
ASN1DN *authority.ASN1DN `json:"asn1dn,omitempty"` ASN1DN *config.ASN1DN `json:"asn1dn,omitempty"`
Claims *config.Claims `json:"claims,omitempty"` Claims *mgmt.Claims `json:"claims,omitempty"`
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
Backdate string `json:"backdate,omitempty"` Backdate string `json:"backdate,omitempty"`
} }
@ -24,9 +23,8 @@ func (car *CreateAuthConfigRequest) Validate() error {
// UpdateAuthConfigRequest represents the body for a UpdateAuthConfig request. // UpdateAuthConfigRequest represents the body for a UpdateAuthConfig request.
type UpdateAuthConfigRequest struct { type UpdateAuthConfigRequest struct {
ASN1DN *authority.ASN1DN `json:"asn1dn"` ASN1DN *config.ASN1DN `json:"asn1dn"`
Claims *config.Claims `json:"claims"` Claims *mgmt.Claims `json:"claims"`
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
Backdate string `json:"backdate,omitempty"` Backdate string `json:"backdate,omitempty"`
} }
@ -53,7 +51,7 @@ func (h *Handler) CreateAuthConfig(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
var body CreateAuthConfigRequest var body CreateAuthConfigRequest
if err := ReadJSON(r.Body, &body); err != nil { if err := api.ReadJSON(r.Body, &body); err != nil {
api.WriteError(w, err) api.WriteError(w, err)
return return
} }
@ -61,9 +59,8 @@ func (h *Handler) CreateAuthConfig(w http.ResponseWriter, r *http.Request) {
api.WriteError(w, err) api.WriteError(w, err)
} }
ac := config.AuthConfig{ ac := &mgmt.AuthConfig{
Status: config.StatusActive, Status: mgmt.StatusActive,
DisableIssuedAtCheck: body.DisableIssuedAtCheck,
Backdate: "1m", Backdate: "1m",
} }
if body.ASN1DN != nil { if body.ASN1DN != nil {
@ -84,11 +81,12 @@ func (h *Handler) CreateAuthConfig(w http.ResponseWriter, r *http.Request) {
// UpdateAuthConfig updates an existing AuthConfig. // UpdateAuthConfig updates an existing AuthConfig.
func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) { func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) {
/*
ctx := r.Context() ctx := r.Context()
id := chi.URLParam(r, "id") id := chi.URLParam(r, "id")
var body UpdateAuthConfigRequest var body UpdateAuthConfigRequest
if err := ReadJSON(r.Body, &body); err != nil { if err := api.ReadJSON(r.Body, &body); err != nil {
api.WriteError(w, err) api.WriteError(w, err)
return return
} }
@ -96,12 +94,12 @@ func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) {
api.WriteError(w, err) api.WriteError(w, err)
return return
} }
if ac, err := h.db.GetAuthConfig(ctx, id); err != nil { ac, err := h.db.GetAuthConfig(ctx, id)
if err != nil {
api.WriteError(w, err) api.WriteError(w, err)
return return
} }
ac.DisableIssuedAtCheck = body.DisableIssuedAtCheck
ac.Status = body.Status ac.Status = body.Status
if body.ASN1DN != nil { if body.ASN1DN != nil {
ac.ASN1DN = body.ASN1DN ac.ASN1DN = body.ASN1DN
@ -118,4 +116,5 @@ func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) {
return return
} }
api.JSON(w, ac) api.JSON(w, ac)
*/
} }

View file

@ -4,7 +4,7 @@ import (
"time" "time"
"github.com/smallstep/certificates/api" "github.com/smallstep/certificates/api"
"github.com/smallstep/certificates/authority/config" "github.com/smallstep/certificates/authority/mgmt"
) )
// Clock that returns time in UTC rounded to seconds. // Clock that returns time in UTC rounded to seconds.
@ -19,14 +19,12 @@ var clock Clock
// Handler is the ACME API request handler. // Handler is the ACME API request handler.
type Handler struct { type Handler struct {
db config.DB db mgmt.DB
} }
// NewHandler returns a new Authority Config Handler. // NewHandler returns a new Authority Config Handler.
func NewHandler(db config.DB) api.RouterHandler { func NewHandler(db mgmt.DB) api.RouterHandler {
return &Handler{ return &Handler{db}
db: ops.DB,
}
} }
// Route traffic and implement the Router interface. // Route traffic and implement the Router interface.

View file

@ -5,14 +5,14 @@ import (
"github.com/go-chi/chi" "github.com/go-chi/chi"
"github.com/smallstep/certificates/api" "github.com/smallstep/certificates/api"
"github.com/smallstep/certificates/authority/config" "github.com/smallstep/certificates/authority/mgmt"
) )
// CreateProvisionerRequest represents the body for a CreateProvisioner request. // CreateProvisionerRequest represents the body for a CreateProvisioner request.
type CreateProvisionerRequest struct { type CreateProvisionerRequest struct {
Type string `json:"type"` Type string `json:"type"`
Name string `json:"name"` Name string `json:"name"`
Claims *config.Claims `json:"claims"` Claims *mgmt.Claims `json:"claims"`
Details interface{} `json:"details"` Details interface{} `json:"details"`
X509Template string `json:"x509Template"` X509Template string `json:"x509Template"`
SSHTemplate string `json:"sshTemplate"` SSHTemplate string `json:"sshTemplate"`
@ -25,7 +25,7 @@ func (car *CreateProvisionerRequest) Validate() error {
// UpdateProvisionerRequest represents the body for a UpdateProvisioner request. // UpdateProvisionerRequest represents the body for a UpdateProvisioner request.
type UpdateProvisionerRequest struct { type UpdateProvisionerRequest struct {
Claims *config.Claims `json:"claims"` Claims *mgmt.Claims `json:"claims"`
Details interface{} `json:"details"` Details interface{} `json:"details"`
X509Template string `json:"x509Template"` X509Template string `json:"x509Template"`
SSHTemplate string `json:"sshTemplate"` SSHTemplate string `json:"sshTemplate"`
@ -66,7 +66,7 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
var body CreateProvisionerRequest var body CreateProvisionerRequest
if err := ReadJSON(r.Body, &body); err != nil { if err := api.ReadJSON(r.Body, &body); err != nil {
api.WriteError(w, err) api.WriteError(w, err)
return return
} }
@ -74,7 +74,7 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
api.WriteError(w, err) api.WriteError(w, err)
} }
prov := &config.Provisioner{ prov := &mgmt.Provisioner{
Type: body.Type, Type: body.Type,
Name: body.Name, Name: body.Name,
Claims: body.Claims, Claims: body.Claims,
@ -91,6 +91,7 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
// UpdateProvisioner updates an existing prov. // UpdateProvisioner updates an existing prov.
func (h *Handler) UpdateProvisioner(w http.ResponseWriter, r *http.Request) { func (h *Handler) UpdateProvisioner(w http.ResponseWriter, r *http.Request) {
/*
ctx := r.Context() ctx := r.Context()
id := chi.URLParam(r, "id") id := chi.URLParam(r, "id")
@ -119,4 +120,5 @@ func (h *Handler) UpdateProvisioner(w http.ResponseWriter, r *http.Request) {
return return
} }
api.JSON(w, prov) api.JSON(w, prov)
*/
} }

View file

@ -19,28 +19,8 @@ type AuthConfig struct {
func NewDefaultAuthConfig() *AuthConfig { func NewDefaultAuthConfig() *AuthConfig {
return &AuthConfig{ return &AuthConfig{
Claims: &Claims{ Claims: NewDefaultClaims(),
X509: &X509Claims{ ASN1DN: &config.ASN1DN{},
Durations: &Durations{
Min: config.GlobalProvisionerClaims.MinTLSDur.String(),
Max: config.GlobalProvisionerClaims.MaxTLSDur.String(),
Default: config.GlobalProvisionerClaims.DefaultTLSDur.String(),
},
},
SSH: &SSHClaims{
UserDurations: &Durations{
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
},
HostDurations: &Durations{
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
},
},
DisableRenewal: config.DefaultDisableRenewal,
},
Backdate: config.DefaultBackdate.String(), Backdate: config.DefaultBackdate.String(),
Status: StatusActive, Status: StatusActive,
} }

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/authority/config"
) )
const ( const (
@ -50,6 +51,31 @@ type Durations struct {
Default string `json:"default"` Default string `json:"default"`
} }
func NewDefaultClaims() *Claims {
return &Claims{
X509: &X509Claims{
Durations: &Durations{
Min: config.GlobalProvisionerClaims.MinTLSDur.String(),
Max: config.GlobalProvisionerClaims.MaxTLSDur.String(),
Default: config.GlobalProvisionerClaims.DefaultTLSDur.String(),
},
},
SSH: &SSHClaims{
UserDurations: &Durations{
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
},
HostDurations: &Durations{
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
},
},
DisableRenewal: config.DefaultDisableRenewal,
}
}
type AuthorityOption func(*AuthConfig) error type AuthorityOption func(*AuthConfig) error
func WithDefaultAuthorityID(ac *AuthConfig) error { func WithDefaultAuthorityID(ac *AuthConfig) error {

View file

@ -18,7 +18,7 @@ type DB interface {
UpdateProvisioner(ctx context.Context, prov *Provisioner) error UpdateProvisioner(ctx context.Context, prov *Provisioner) error
CreateAdmin(ctx context.Context, admin *Admin) error CreateAdmin(ctx context.Context, admin *Admin) error
GetAdmin(ctx context.Context, id string) error GetAdmin(ctx context.Context, id string) (*Admin, error)
GetAdmins(ctx context.Context) ([]*Admin, error) GetAdmins(ctx context.Context) ([]*Admin, error)
UpdateAdmin(ctx context.Context, admin *Admin) error UpdateAdmin(ctx context.Context, admin *Admin) error
@ -116,7 +116,7 @@ func (m *MockDB) GetAdmins(ctx context.Context) ([]*Admin, error) {
// UpdateAdmin mock // UpdateAdmin mock
func (m *MockDB) UpdateAdmin(ctx context.Context, adm *Admin) error { func (m *MockDB) UpdateAdmin(ctx context.Context, adm *Admin) error {
if m.UpdateAdmin != nil { if m.MockUpdateAdmin != nil {
return m.MockUpdateAdmin(ctx, adm) return m.MockUpdateAdmin(ctx, adm)
} }
return m.MockError return m.MockError
@ -142,7 +142,7 @@ func (m *MockDB) GetAuthConfig(ctx context.Context, id string) (*AuthConfig, err
// UpdateAuthConfig mock // UpdateAuthConfig mock
func (m *MockDB) UpdateAuthConfig(ctx context.Context, adm *AuthConfig) error { func (m *MockDB) UpdateAuthConfig(ctx context.Context, adm *AuthConfig) error {
if m.UpdateAuthConfig != nil { if m.MockUpdateAuthConfig != nil {
return m.MockUpdateAuthConfig(ctx, adm) return m.MockUpdateAuthConfig(ctx, adm)
} }
return m.MockError return m.MockError

View file

@ -6,7 +6,6 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/acme"
"github.com/smallstep/certificates/authority/mgmt" "github.com/smallstep/certificates/authority/mgmt"
"github.com/smallstep/nosql" "github.com/smallstep/nosql"
) )
@ -109,7 +108,7 @@ func unmarshalAdmin(data []byte, id string) (*mgmt.Admin, error) {
// GetAdmins retrieves and unmarshals all active (not deleted) admins // GetAdmins retrieves and unmarshals all active (not deleted) admins
// from the database. // from the database.
// TODO should we be paginating? // TODO should we be paginating?
func (db *DB) GetAdmins(ctx context.Context, az *acme.Authorization) ([]*mgmt.Admin, error) { func (db *DB) GetAdmins(ctx context.Context) ([]*mgmt.Admin, error) {
dbEntries, err := db.db.List(authorityAdminsTable) dbEntries, err := db.db.List(authorityAdminsTable)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "error loading admins") return nil, errors.Wrap(err, "error loading admins")

View file

@ -15,7 +15,6 @@ type dbAuthConfig struct {
ID string `json:"id"` ID string `json:"id"`
ASN1DN *config.ASN1DN `json:"asn1dn"` ASN1DN *config.ASN1DN `json:"asn1dn"`
Claims *mgmt.Claims `json:"claims"` Claims *mgmt.Claims `json:"claims"`
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
Backdate string `json:"backdate,omitempty"` Backdate string `json:"backdate,omitempty"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
DeletedAt time.Time `json:"deletedAt"` DeletedAt time.Time `json:"deletedAt"`
@ -68,23 +67,23 @@ func (db *DB) GetAuthConfig(ctx context.Context, id string) (*mgmt.AuthConfig, e
ASN1DN: dba.ASN1DN, ASN1DN: dba.ASN1DN,
Backdate: dba.Backdate, Backdate: dba.Backdate,
Claims: dba.Claims, Claims: dba.Claims,
DisableIssuedAtCheck: dba.DisableIssuedAtCheck,
}, nil }, nil
} }
// CreateAuthConfig stores a new provisioner to the database. // CreateAuthConfig stores a new provisioner to the database.
func (db *DB) CreateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error { func (db *DB) CreateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
var err error var err error
if ac.ID == "" {
ac.ID, err = randID() ac.ID, err = randID()
if err != nil { if err != nil {
return errors.Wrap(err, "error generating random id for provisioner") return errors.Wrap(err, "error generating random id for provisioner")
} }
}
dba := &dbAuthConfig{ dba := &dbAuthConfig{
ID: ac.ID, ID: ac.ID,
ASN1DN: ac.ASN1DN, ASN1DN: ac.ASN1DN,
Claims: ac.Claims, Claims: ac.Claims,
DisableIssuedAtCheck: ac.DisableIssuedAtCheck,
Backdate: ac.Backdate, Backdate: ac.Backdate,
CreatedAt: clock.Now(), CreatedAt: clock.Now(),
} }
@ -106,7 +105,6 @@ func (db *DB) UpdateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
nu.DeletedAt = clock.Now() nu.DeletedAt = clock.Now()
} }
nu.Claims = ac.Claims nu.Claims = ac.Claims
nu.DisableIssuedAtCheck = ac.DisableIssuedAtCheck
nu.Backdate = ac.Backdate nu.Backdate = ac.Backdate
return db.save(ctx, old.ID, nu, old, "authConfig", authorityProvisionersTable) return db.save(ctx, old.ID, nu, old, "authConfig", authorityProvisionersTable)

View file

@ -87,6 +87,11 @@ type Error struct {
Status int `json:"-"` Status int `json:"-"`
} }
// IsType returns true if the error type matches the input type.
func (e *Error) IsType(pt ProblemType) bool {
return pt.String() == e.Type
}
// NewError creates a new Error type. // NewError creates a new Error type.
func NewError(pt ProblemType, msg string, args ...interface{}) *Error { func NewError(pt ProblemType, msg string, args ...interface{}) *Error {
return newError(pt, errors.Errorf(msg, args...)) return newError(pt, errors.Errorf(msg, args...))

View file

@ -20,6 +20,16 @@ type ProvisionerCtx struct {
Password string Password string
} }
func NewProvisionerCtx(opts ...ProvisionerOption) *ProvisionerCtx {
pc := &ProvisionerCtx{
Claims: NewDefaultClaims(),
}
for _, o := range opts {
o(pc)
}
return pc
}
func WithJWK(jwk *jose.JSONWebKey, jwe *jose.JSONWebEncryption) func(*ProvisionerCtx) { func WithJWK(jwk *jose.JSONWebKey, jwe *jose.JSONWebEncryption) func(*ProvisionerCtx) {
return func(ctx *ProvisionerCtx) { return func(ctx *ProvisionerCtx) {
ctx.JWK = jwk ctx.JWK = jwk
@ -62,10 +72,7 @@ func (p *Provisioner) GetOptions() *provisioner.Options {
} }
func CreateProvisioner(ctx context.Context, db DB, typ, name string, opts ...ProvisionerOption) (*Provisioner, error) { func CreateProvisioner(ctx context.Context, db DB, typ, name string, opts ...ProvisionerOption) (*Provisioner, error) {
pc := new(ProvisionerCtx) pc := NewProvisionerCtx(opts...)
for _, o := range opts {
o(pc)
}
details, err := createJWKDetails(pc) details, err := createJWKDetails(pc)
if err != nil { if err != nil {

View file

@ -18,6 +18,7 @@ import (
"github.com/smallstep/certificates/authority" "github.com/smallstep/certificates/authority"
"github.com/smallstep/certificates/authority/config" "github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/mgmt" "github.com/smallstep/certificates/authority/mgmt"
mgmtAPI "github.com/smallstep/certificates/authority/mgmt/api"
"github.com/smallstep/certificates/db" "github.com/smallstep/certificates/db"
"github.com/smallstep/certificates/logging" "github.com/smallstep/certificates/logging"
"github.com/smallstep/certificates/monitoring" "github.com/smallstep/certificates/monitoring"
@ -143,6 +144,7 @@ func (ca *CA) Init(config *config.Config) (*CA, error) {
dns = fmt.Sprintf("%s:%s", dns, port) dns = fmt.Sprintf("%s:%s", dns, port)
} }
// ACME Router
prefix := "acme" prefix := "acme"
var acmeDB acme.DB var acmeDB acme.DB
if config.DB == nil { if config.DB == nil {
@ -169,6 +171,16 @@ func (ca *CA) Init(config *config.Config) (*CA, error) {
acmeHandler.Route(r) acmeHandler.Route(r)
}) })
// MGMT Router
mgmtDB := auth.GetMgmtDatabase()
if mgmtDB != nil {
mgmtHandler := mgmtAPI.NewHandler(mgmtDB)
mux.Route("/mgmt", func(r chi.Router) {
mgmtHandler.Route(r)
})
}
// helpful routine for logging all routes // // helpful routine for logging all routes //
/* /*
walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error { walkFunc := func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {

View file

@ -60,10 +60,10 @@ func (c *MgmtClient) retryOnError(r *http.Response) bool {
return false return false
} }
// GetAdmin performs the GET /config/admin/{id} request to the CA. // GetAdmin performs the GET /mgmt/admin/{id} request to the CA.
func (c *MgmtClient) GetAdmin(id string) (*mgmt.Admin, error) { func (c *MgmtClient) GetAdmin(id string) (*mgmt.Admin, error) {
var retried bool var retried bool
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/config/admin", id)}) u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/mgmt/admin", id)})
retry: retry:
resp, err := c.client.Get(u.String()) resp, err := c.client.Get(u.String())
if err != nil { if err != nil {
@ -83,10 +83,10 @@ retry:
return adm, nil return adm, nil
} }
// GetAdmins performs the GET /config/admins request to the CA. // GetAdmins performs the GET /mgmt/admins request to the CA.
func (c *MgmtClient) GetAdmins() ([]*mgmt.Admin, error) { func (c *MgmtClient) GetAdmins() ([]*mgmt.Admin, error) {
var retried bool var retried bool
u := c.endpoint.ResolveReference(&url.URL{Path: "/config/admins"}) u := c.endpoint.ResolveReference(&url.URL{Path: "/mgmt/admins"})
retry: retry:
resp, err := c.client.Get(u.String()) resp, err := c.client.Get(u.String())
if err != nil { if err != nil {