forked from TrueCloudLab/certificates
wip
This commit is contained in:
parent
01a4460812
commit
94ba057f01
5 changed files with 77 additions and 21 deletions
|
@ -130,6 +130,7 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReloadAuthConfig reloads dynamic fields of the AuthConfig.
|
||||||
func (a *Authority) ReloadAuthConfig(ctx context.Context) error {
|
func (a *Authority) ReloadAuthConfig(ctx context.Context) error {
|
||||||
provs, err := a.adminDB.GetProvisioners(ctx)
|
provs, err := a.adminDB.GetProvisioners(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -218,14 +219,20 @@ func (a *Authority) init() error {
|
||||||
|
|
||||||
provs, err := a.adminDB.GetProvisioners(context.Background())
|
provs, err := a.adminDB.GetProvisioners(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return mgmt.WrapErrorISE(err, "error getting provisioners to initialize authority")
|
||||||
}
|
}
|
||||||
if len(provs) == 0 {
|
if len(provs) == 0 {
|
||||||
// Create First Provisioner
|
// Create First Provisioner
|
||||||
prov, err := mgmt.CreateFirstProvisioner(context.Background(), a.adminDB, a.config.Password)
|
prov, err := mgmt.CreateFirstProvisioner(context.Background(), a.adminDB, a.config.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return mgmt.WrapErrorISE(err, "error creating first provisioner")
|
||||||
}
|
}
|
||||||
|
certProv, err := provisionerToCertificates(prov)
|
||||||
|
if err != nil {
|
||||||
|
return mgmt.WrapErrorISE(err, "error converting provisioner to certificates type")
|
||||||
|
}
|
||||||
|
a.config.AuthorityConfig.Provisioners = []provisioner.Interface{certProv}
|
||||||
|
|
||||||
// Create First Admin
|
// Create First Admin
|
||||||
adm := &linkedca.Admin{
|
adm := &linkedca.Admin{
|
||||||
ProvisionerId: prov.Id,
|
ProvisionerId: prov.Id,
|
||||||
|
@ -238,13 +245,9 @@ func (a *Authority) init() error {
|
||||||
}
|
}
|
||||||
a.config.AuthorityConfig.Admins = []*linkedca.Admin{adm}
|
a.config.AuthorityConfig.Admins = []*linkedca.Admin{adm}
|
||||||
} else {
|
} else {
|
||||||
provs, err := a.adminDB.GetProvisioners(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
return mgmt.WrapErrorISE(err, "error getting provisioners to initialize authority")
|
|
||||||
}
|
|
||||||
a.config.AuthorityConfig.Provisioners, err = provisionerListToCertificates(provs)
|
a.config.AuthorityConfig.Provisioners, err = provisionerListToCertificates(provs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mgmt.WrapErrorISE(err, "error converting provisioner list to certificates")
|
return mgmt.WrapErrorISE(err, "error converting provisioner list to certificates type")
|
||||||
}
|
}
|
||||||
a.config.AuthorityConfig.Admins, err = a.adminDB.GetAdmins(context.Background())
|
a.config.AuthorityConfig.Admins, err = a.adminDB.GetAdmins(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -151,7 +151,7 @@ func (db *DB) CreateProvisioner(ctx context.Context, prov *linkedca.Provisioner)
|
||||||
return errors.Wrap(err, "error generating random id for provisioner")
|
return errors.Wrap(err, "error generating random id for provisioner")
|
||||||
}
|
}
|
||||||
|
|
||||||
details, err := json.Marshal(prov.Details)
|
details, err := json.Marshal(prov.Details.GetData())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mgmt.WrapErrorISE(err, "error marshaling details when creating provisioner %s", prov.Name)
|
return mgmt.WrapErrorISE(err, "error marshaling details when creating provisioner %s", prov.Name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ func CreateFirstProvisioner(ctx context.Context, db DB, password string) (*linke
|
||||||
return nil, WrapErrorISE(err, "error serializing JWE")
|
return nil, WrapErrorISE(err, "error serializing JWE")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &linkedca.Provisioner{
|
p := &linkedca.Provisioner{
|
||||||
Name: "Admin JWK",
|
Name: "Admin JWK",
|
||||||
Type: linkedca.Provisioner_JWK,
|
Type: linkedca.Provisioner_JWK,
|
||||||
Claims: NewDefaultClaims(),
|
Claims: NewDefaultClaims(),
|
||||||
|
@ -108,5 +108,9 @@ func CreateFirstProvisioner(ctx context.Context, db DB, password string) (*linke
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}
|
||||||
|
if err := db.CreateProvisioner(ctx, p); err != nil {
|
||||||
|
return nil, WrapErrorISE(err, "error creating provisioner")
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ func provisionerToCertificates(p *linkedca.Provisioner) (provisioner.Interface,
|
||||||
|
|
||||||
switch d := details.(type) {
|
switch d := details.(type) {
|
||||||
case *linkedca.ProvisionerDetails_JWK:
|
case *linkedca.ProvisionerDetails_JWK:
|
||||||
|
fmt.Printf("d = %+v\n", d)
|
||||||
jwk := new(jose.JSONWebKey)
|
jwk := new(jose.JSONWebKey)
|
||||||
if err := json.Unmarshal(d.JWK.PublicKey, &jwk); err != nil {
|
if err := json.Unmarshal(d.JWK.PublicKey, &jwk); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/authority/mgmt"
|
"github.com/smallstep/certificates/authority/mgmt"
|
||||||
mgmtAPI "github.com/smallstep/certificates/authority/mgmt/api"
|
mgmtAPI "github.com/smallstep/certificates/authority/mgmt/api"
|
||||||
|
"github.com/smallstep/certificates/authority/provisioner"
|
||||||
"github.com/smallstep/certificates/errs"
|
"github.com/smallstep/certificates/errs"
|
||||||
"github.com/smallstep/certificates/linkedca"
|
"github.com/smallstep/certificates/linkedca"
|
||||||
)
|
)
|
||||||
|
@ -92,7 +93,7 @@ retry:
|
||||||
return adm, nil
|
return adm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminOption is the type of options passed to the Provisioner method.
|
// AdminOption is the type of options passed to the Admin method.
|
||||||
type AdminOption func(o *adminOptions) error
|
type AdminOption func(o *adminOptions) error
|
||||||
|
|
||||||
type adminOptions struct {
|
type adminOptions struct {
|
||||||
|
@ -136,8 +137,8 @@ func WithAdminLimit(limit int) AdminOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAdmins performs the GET /admin/admins request to the CA.
|
// GetAdminsPaginate returns a page from the the GET /admin/admins request to the CA.
|
||||||
func (c *AdminClient) GetAdmins(opts ...AdminOption) (*mgmtAPI.GetAdminsResponse, error) {
|
func (c *AdminClient) GetAdminsPaginate(opts ...AdminOption) (*mgmtAPI.GetAdminsResponse, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
o := new(adminOptions)
|
o := new(adminOptions)
|
||||||
if err := o.apply(opts); err != nil {
|
if err := o.apply(opts); err != nil {
|
||||||
|
@ -166,6 +167,26 @@ retry:
|
||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAdmins returns all admins from the GET /admin/admins request to the CA.
|
||||||
|
func (c *AdminClient) GetAdmins(opts ...AdminOption) ([]*linkedca.Admin, error) {
|
||||||
|
var (
|
||||||
|
cursor = ""
|
||||||
|
admins = []*linkedca.Admin{}
|
||||||
|
)
|
||||||
|
for {
|
||||||
|
resp, err := c.GetAdminsPaginate(WithAdminCursor(cursor), WithAdminLimit(100))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
admins = append(admins, resp.Admins...)
|
||||||
|
if resp.NextCursor == "" {
|
||||||
|
return admins, nil
|
||||||
|
}
|
||||||
|
cursor = resp.NextCursor
|
||||||
|
}
|
||||||
|
return admins, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateAdmin performs the POST /admin/admins request to the CA.
|
// CreateAdmin performs the POST /admin/admins request to the CA.
|
||||||
func (c *AdminClient) CreateAdmin(req *mgmtAPI.CreateAdminRequest) (*linkedca.Admin, error) {
|
func (c *AdminClient) CreateAdmin(req *mgmtAPI.CreateAdminRequest) (*linkedca.Admin, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
|
@ -247,8 +268,8 @@ retry:
|
||||||
return adm, nil
|
return adm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProvisioner performs the GET /admin/provisioners/{name} request to the CA.
|
// GetProvisionerByName performs the GET /admin/provisioners/{name} request to the CA.
|
||||||
func (c *AdminClient) GetProvisioner(name string) (*linkedca.Provisioner, error) {
|
func (c *AdminClient) GetProvisionerByName(name string) (*linkedca.Provisioner, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", name)})
|
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", name)})
|
||||||
retry:
|
retry:
|
||||||
|
@ -270,10 +291,17 @@ retry:
|
||||||
return prov, nil
|
return prov, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProvisioners performs the GET /admin/provisioners request to the CA.
|
// GetProvisionersPaginate performs the GET /admin/provisioners request to the CA.
|
||||||
func (c *AdminClient) GetProvisioners() ([]*linkedca.Provisioner, error) {
|
func (c *AdminClient) GetProvisionersPaginate(opts ...ProvisionerOption) (*mgmtAPI.GetProvisionersResponse, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/provisioners"})
|
o := new(provisionerOptions)
|
||||||
|
if err := o.apply(opts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u := c.endpoint.ResolveReference(&url.URL{
|
||||||
|
Path: "/admin/provisioners",
|
||||||
|
RawQuery: o.rawQuery(),
|
||||||
|
})
|
||||||
retry:
|
retry:
|
||||||
resp, err := c.client.Get(u.String())
|
resp, err := c.client.Get(u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -286,11 +314,31 @@ retry:
|
||||||
}
|
}
|
||||||
return nil, readAdminError(resp.Body)
|
return nil, readAdminError(resp.Body)
|
||||||
}
|
}
|
||||||
var provs = new([]*linkedca.Provisioner)
|
var body = new(mgmtAPI.GetProvisionersResponse)
|
||||||
if err := readJSON(resp.Body, provs); err != nil {
|
if err := readJSON(resp.Body, body); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||||
}
|
}
|
||||||
return *provs, nil
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProvisioners returns all admins from the GET /admin/admins request to the CA.
|
||||||
|
func (c *AdminClient) GetProvisioners(opts ...AdminOption) (provisioner.List, error) {
|
||||||
|
var (
|
||||||
|
cursor = ""
|
||||||
|
provs = provisioner.List{}
|
||||||
|
)
|
||||||
|
for {
|
||||||
|
resp, err := c.GetProvisionersPaginate(WithProvisionerCursor(cursor), WithProvisionerLimit(100))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
provs = append(provs, resp.Provisioners...)
|
||||||
|
if resp.NextCursor == "" {
|
||||||
|
return provs, nil
|
||||||
|
}
|
||||||
|
cursor = resp.NextCursor
|
||||||
|
}
|
||||||
|
return provs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveProvisioner performs the DELETE /admin/provisioners/{name} request to the CA.
|
// RemoveProvisioner performs the DELETE /admin/provisioners/{name} request to the CA.
|
||||||
|
|
Loading…
Reference in a new issue