2021-05-03 19:48:20 +00:00
|
|
|
package admin
|
2021-05-03 19:48:20 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-05-03 19:48:20 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2021-05-03 19:48:20 +00:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2021-05-03 19:48:20 +00:00
|
|
|
"go.step.sm/linkedca"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// DefaultAuthorityID is the default AuthorityID. This will be the ID
|
|
|
|
// of the first Authority created, as well as the default AuthorityID
|
|
|
|
// if one is not specified in the configuration.
|
|
|
|
DefaultAuthorityID = "00000000-0000-0000-0000-000000000000"
|
2021-05-03 19:48:20 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ErrNotFound is an error that should be used by the authority.DB interface to
|
|
|
|
// indicate that an entity does not exist.
|
|
|
|
var ErrNotFound = errors.New("not found")
|
|
|
|
|
2021-05-03 19:48:20 +00:00
|
|
|
// UnmarshalProvisionerDetails unmarshals details type to the specific provisioner details.
|
|
|
|
func UnmarshalProvisionerDetails(typ linkedca.Provisioner_Type, data []byte) (*linkedca.ProvisionerDetails, error) {
|
|
|
|
var v linkedca.ProvisionerDetails
|
|
|
|
switch typ {
|
|
|
|
case linkedca.Provisioner_JWK:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_JWK)
|
|
|
|
case linkedca.Provisioner_OIDC:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_OIDC)
|
|
|
|
case linkedca.Provisioner_GCP:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_GCP)
|
|
|
|
case linkedca.Provisioner_AWS:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_AWS)
|
|
|
|
case linkedca.Provisioner_AZURE:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_Azure)
|
|
|
|
case linkedca.Provisioner_ACME:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_ACME)
|
|
|
|
case linkedca.Provisioner_X5C:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_X5C)
|
|
|
|
case linkedca.Provisioner_K8SSA:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_K8SSA)
|
|
|
|
case linkedca.Provisioner_SSHPOP:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_SSHPOP)
|
|
|
|
case linkedca.Provisioner_SCEP:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_SCEP)
|
2022-01-05 02:42:57 +00:00
|
|
|
case linkedca.Provisioner_NEBULA:
|
|
|
|
v.Data = new(linkedca.ProvisionerDetails_Nebula)
|
2021-05-03 19:48:20 +00:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unsupported provisioner type %s", typ)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := json.Unmarshal(data, v.Data); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &linkedca.ProvisionerDetails{Data: v.Data}, nil
|
|
|
|
}
|
|
|
|
|
2021-09-22 18:56:52 +00:00
|
|
|
// DB is the DB interface expected by the step-ca Admin API.
|
2021-05-03 19:48:20 +00:00
|
|
|
type DB interface {
|
2021-05-24 20:38:24 +00:00
|
|
|
CreateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error
|
|
|
|
GetProvisioner(ctx context.Context, id string) (*linkedca.Provisioner, error)
|
|
|
|
GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error)
|
|
|
|
UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error
|
2021-05-25 23:52:06 +00:00
|
|
|
DeleteProvisioner(ctx context.Context, id string) error
|
2021-05-24 20:38:24 +00:00
|
|
|
|
|
|
|
CreateAdmin(ctx context.Context, admin *linkedca.Admin) error
|
|
|
|
GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error)
|
|
|
|
GetAdmins(ctx context.Context) ([]*linkedca.Admin, error)
|
|
|
|
UpdateAdmin(ctx context.Context, admin *linkedca.Admin) error
|
2021-05-25 23:52:06 +00:00
|
|
|
DeleteAdmin(ctx context.Context, id string) error
|
2022-03-15 14:51:45 +00:00
|
|
|
|
|
|
|
CreateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error
|
|
|
|
GetAuthorityPolicy(ctx context.Context) (*linkedca.Policy, error)
|
|
|
|
UpdateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error
|
|
|
|
DeleteAuthorityPolicy(ctx context.Context) error
|
2021-05-03 19:48:20 +00:00
|
|
|
}
|
|
|
|
|
2022-04-27 18:58:52 +00:00
|
|
|
type dbKey struct{}
|
|
|
|
|
|
|
|
// NewContext adds the given admin database to the context.
|
|
|
|
func NewContext(ctx context.Context, db DB) context.Context {
|
|
|
|
return context.WithValue(ctx, dbKey{}, db)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromContext returns the current admin database from the given context.
|
|
|
|
func FromContext(ctx context.Context) (db DB, ok bool) {
|
|
|
|
db, ok = ctx.Value(dbKey{}).(DB)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// MustFromContext returns the current admin database from the given context. It
|
|
|
|
// will panic if it's not in the context.
|
|
|
|
func MustFromContext(ctx context.Context) DB {
|
|
|
|
if db, ok := FromContext(ctx); !ok {
|
|
|
|
panic("admin database is not in the context")
|
|
|
|
} else {
|
|
|
|
return db
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-03 19:48:20 +00:00
|
|
|
// MockDB is an implementation of the DB interface that should only be used as
|
|
|
|
// a mock in tests.
|
|
|
|
type MockDB struct {
|
2021-05-24 20:38:24 +00:00
|
|
|
MockCreateProvisioner func(ctx context.Context, prov *linkedca.Provisioner) error
|
|
|
|
MockGetProvisioner func(ctx context.Context, id string) (*linkedca.Provisioner, error)
|
|
|
|
MockGetProvisioners func(ctx context.Context) ([]*linkedca.Provisioner, error)
|
|
|
|
MockUpdateProvisioner func(ctx context.Context, prov *linkedca.Provisioner) error
|
2021-05-25 23:52:06 +00:00
|
|
|
MockDeleteProvisioner func(ctx context.Context, id string) error
|
2021-05-03 19:48:20 +00:00
|
|
|
|
2021-05-24 20:38:24 +00:00
|
|
|
MockCreateAdmin func(ctx context.Context, adm *linkedca.Admin) error
|
|
|
|
MockGetAdmin func(ctx context.Context, id string) (*linkedca.Admin, error)
|
|
|
|
MockGetAdmins func(ctx context.Context) ([]*linkedca.Admin, error)
|
|
|
|
MockUpdateAdmin func(ctx context.Context, adm *linkedca.Admin) error
|
2021-05-25 23:52:06 +00:00
|
|
|
MockDeleteAdmin func(ctx context.Context, id string) error
|
2021-05-03 19:48:20 +00:00
|
|
|
|
2022-03-15 14:51:45 +00:00
|
|
|
MockCreateAuthorityPolicy func(ctx context.Context, policy *linkedca.Policy) error
|
|
|
|
MockGetAuthorityPolicy func(ctx context.Context) (*linkedca.Policy, error)
|
|
|
|
MockUpdateAuthorityPolicy func(ctx context.Context, policy *linkedca.Policy) error
|
|
|
|
MockDeleteAuthorityPolicy func(ctx context.Context) error
|
|
|
|
|
2021-05-03 19:48:20 +00:00
|
|
|
MockError error
|
|
|
|
MockRet1 interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateProvisioner mock.
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) CreateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockCreateProvisioner != nil {
|
|
|
|
return m.MockCreateProvisioner(ctx, prov)
|
|
|
|
} else if m.MockError != nil {
|
|
|
|
return m.MockError
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetProvisioner mock.
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) GetProvisioner(ctx context.Context, id string) (*linkedca.Provisioner, error) {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockGetProvisioner != nil {
|
|
|
|
return m.MockGetProvisioner(ctx, id)
|
|
|
|
} else if m.MockError != nil {
|
|
|
|
return nil, m.MockError
|
|
|
|
}
|
2021-05-24 20:38:24 +00:00
|
|
|
return m.MockRet1.(*linkedca.Provisioner), m.MockError
|
2021-05-03 19:48:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetProvisioners mock
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error) {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockGetProvisioners != nil {
|
|
|
|
return m.MockGetProvisioners(ctx)
|
|
|
|
} else if m.MockError != nil {
|
|
|
|
return nil, m.MockError
|
|
|
|
}
|
2021-05-24 20:38:24 +00:00
|
|
|
return m.MockRet1.([]*linkedca.Provisioner), m.MockError
|
2021-05-03 19:48:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateProvisioner mock
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockUpdateProvisioner != nil {
|
2021-05-18 23:50:54 +00:00
|
|
|
return m.MockUpdateProvisioner(ctx, prov)
|
2021-05-03 19:48:20 +00:00
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
|
|
|
|
2021-05-25 23:52:06 +00:00
|
|
|
// DeleteProvisioner mock
|
|
|
|
func (m *MockDB) DeleteProvisioner(ctx context.Context, id string) error {
|
|
|
|
if m.MockDeleteProvisioner != nil {
|
|
|
|
return m.MockDeleteProvisioner(ctx, id)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
|
|
|
|
2021-05-03 19:48:20 +00:00
|
|
|
// CreateAdmin mock
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) CreateAdmin(ctx context.Context, admin *linkedca.Admin) error {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockCreateAdmin != nil {
|
|
|
|
return m.MockCreateAdmin(ctx, admin)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAdmin mock.
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error) {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockGetAdmin != nil {
|
|
|
|
return m.MockGetAdmin(ctx, id)
|
|
|
|
} else if m.MockError != nil {
|
|
|
|
return nil, m.MockError
|
|
|
|
}
|
2021-05-24 20:38:24 +00:00
|
|
|
return m.MockRet1.(*linkedca.Admin), m.MockError
|
2021-05-03 19:48:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetAdmins mock
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) GetAdmins(ctx context.Context) ([]*linkedca.Admin, error) {
|
2021-05-03 19:48:20 +00:00
|
|
|
if m.MockGetAdmins != nil {
|
|
|
|
return m.MockGetAdmins(ctx)
|
|
|
|
} else if m.MockError != nil {
|
|
|
|
return nil, m.MockError
|
|
|
|
}
|
2021-05-24 20:38:24 +00:00
|
|
|
return m.MockRet1.([]*linkedca.Admin), m.MockError
|
2021-05-03 19:48:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateAdmin mock
|
2021-05-24 20:38:24 +00:00
|
|
|
func (m *MockDB) UpdateAdmin(ctx context.Context, adm *linkedca.Admin) error {
|
2021-05-07 00:03:12 +00:00
|
|
|
if m.MockUpdateAdmin != nil {
|
2021-05-03 19:48:20 +00:00
|
|
|
return m.MockUpdateAdmin(ctx, adm)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
2021-05-25 23:52:06 +00:00
|
|
|
|
|
|
|
// DeleteAdmin mock
|
|
|
|
func (m *MockDB) DeleteAdmin(ctx context.Context, id string) error {
|
|
|
|
if m.MockDeleteAdmin != nil {
|
|
|
|
return m.MockDeleteAdmin(ctx, id)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
2022-03-15 14:51:45 +00:00
|
|
|
|
2022-04-19 15:10:13 +00:00
|
|
|
// CreateAuthorityPolicy mock
|
2022-03-15 14:51:45 +00:00
|
|
|
func (m *MockDB) CreateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
|
|
|
|
if m.MockCreateAuthorityPolicy != nil {
|
|
|
|
return m.MockCreateAuthorityPolicy(ctx, policy)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
2022-04-19 15:10:13 +00:00
|
|
|
|
|
|
|
// GetAuthorityPolicy mock
|
2022-03-15 14:51:45 +00:00
|
|
|
func (m *MockDB) GetAuthorityPolicy(ctx context.Context) (*linkedca.Policy, error) {
|
|
|
|
if m.MockGetAuthorityPolicy != nil {
|
|
|
|
return m.MockGetAuthorityPolicy(ctx)
|
|
|
|
}
|
|
|
|
return m.MockRet1.(*linkedca.Policy), m.MockError
|
|
|
|
}
|
|
|
|
|
2022-04-19 15:10:13 +00:00
|
|
|
// UpdateAuthorityPolicy mock
|
2022-03-15 14:51:45 +00:00
|
|
|
func (m *MockDB) UpdateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
|
|
|
|
if m.MockUpdateAuthorityPolicy != nil {
|
|
|
|
return m.MockUpdateAuthorityPolicy(ctx, policy)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|
|
|
|
|
2022-04-19 15:10:13 +00:00
|
|
|
// DeleteAuthorityPolicy mock
|
2022-03-15 14:51:45 +00:00
|
|
|
func (m *MockDB) DeleteAuthorityPolicy(ctx context.Context) error {
|
|
|
|
if m.MockDeleteAuthorityPolicy != nil {
|
|
|
|
return m.MockDeleteAuthorityPolicy(ctx)
|
|
|
|
}
|
|
|
|
return m.MockError
|
|
|
|
}
|