1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
|
package admin
import (
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"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"
)
// 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")
// 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)
case linkedca.Provisioner_NEBULA:
v.Data = new(linkedca.ProvisionerDetails_Nebula)
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
}
// DB is the DB interface expected by the step-ca Admin API.
type DB interface {
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
DeleteProvisioner(ctx context.Context, id string) error
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
DeleteAdmin(ctx context.Context, id string) error
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
}
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
}
}
// MockDB is an implementation of the DB interface that should only be used as
// a mock in tests.
type MockDB struct {
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
MockDeleteProvisioner func(ctx context.Context, id string) error
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
MockDeleteAdmin func(ctx context.Context, id string) error
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
MockError error
MockRet1 interface{}
}
// CreateProvisioner mock.
func (m *MockDB) CreateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
if m.MockCreateProvisioner != nil {
return m.MockCreateProvisioner(ctx, prov)
} else if m.MockError != nil {
return m.MockError
}
return m.MockError
}
// GetProvisioner mock.
func (m *MockDB) GetProvisioner(ctx context.Context, id string) (*linkedca.Provisioner, error) {
if m.MockGetProvisioner != nil {
return m.MockGetProvisioner(ctx, id)
} else if m.MockError != nil {
return nil, m.MockError
}
return m.MockRet1.(*linkedca.Provisioner), m.MockError
}
// GetProvisioners mock
func (m *MockDB) GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error) {
if m.MockGetProvisioners != nil {
return m.MockGetProvisioners(ctx)
} else if m.MockError != nil {
return nil, m.MockError
}
return m.MockRet1.([]*linkedca.Provisioner), m.MockError
}
// UpdateProvisioner mock
func (m *MockDB) UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
if m.MockUpdateProvisioner != nil {
return m.MockUpdateProvisioner(ctx, prov)
}
return m.MockError
}
// DeleteProvisioner mock
func (m *MockDB) DeleteProvisioner(ctx context.Context, id string) error {
if m.MockDeleteProvisioner != nil {
return m.MockDeleteProvisioner(ctx, id)
}
return m.MockError
}
// CreateAdmin mock
func (m *MockDB) CreateAdmin(ctx context.Context, admin *linkedca.Admin) error {
if m.MockCreateAdmin != nil {
return m.MockCreateAdmin(ctx, admin)
}
return m.MockError
}
// GetAdmin mock.
func (m *MockDB) GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error) {
if m.MockGetAdmin != nil {
return m.MockGetAdmin(ctx, id)
} else if m.MockError != nil {
return nil, m.MockError
}
return m.MockRet1.(*linkedca.Admin), m.MockError
}
// GetAdmins mock
func (m *MockDB) GetAdmins(ctx context.Context) ([]*linkedca.Admin, error) {
if m.MockGetAdmins != nil {
return m.MockGetAdmins(ctx)
} else if m.MockError != nil {
return nil, m.MockError
}
return m.MockRet1.([]*linkedca.Admin), m.MockError
}
// UpdateAdmin mock
func (m *MockDB) UpdateAdmin(ctx context.Context, adm *linkedca.Admin) error {
if m.MockUpdateAdmin != nil {
return m.MockUpdateAdmin(ctx, adm)
}
return m.MockError
}
// DeleteAdmin mock
func (m *MockDB) DeleteAdmin(ctx context.Context, id string) error {
if m.MockDeleteAdmin != nil {
return m.MockDeleteAdmin(ctx, id)
}
return m.MockError
}
// CreateAuthorityPolicy mock
func (m *MockDB) CreateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
if m.MockCreateAuthorityPolicy != nil {
return m.MockCreateAuthorityPolicy(ctx, policy)
}
return m.MockError
}
// GetAuthorityPolicy mock
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
}
// UpdateAuthorityPolicy mock
func (m *MockDB) UpdateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
if m.MockUpdateAuthorityPolicy != nil {
return m.MockUpdateAuthorityPolicy(ctx, policy)
}
return m.MockError
}
// DeleteAuthorityPolicy mock
func (m *MockDB) DeleteAuthorityPolicy(ctx context.Context) error {
if m.MockDeleteAuthorityPolicy != nil {
return m.MockDeleteAuthorityPolicy(ctx)
}
return m.MockError
}
|