smallstep-certificates/authority/admin/db/nosql/policy.go
2022-04-18 21:14:30 +02:00

122 lines
3.1 KiB
Go

package nosql
import (
"context"
"encoding/json"
"fmt"
"go.step.sm/linkedca"
"github.com/smallstep/certificates/authority/admin"
"github.com/smallstep/nosql"
)
type dbAuthorityPolicy struct {
ID string `json:"id"`
AuthorityID string `json:"authorityID"`
Policy *linkedca.Policy `json:"policy"`
}
func (dbap *dbAuthorityPolicy) convert() *linkedca.Policy {
if dbap == nil {
return nil
}
return dbap.Policy
}
func (db *DB) getDBAuthorityPolicyBytes(ctx context.Context, authorityID string) ([]byte, error) {
data, err := db.db.Get(authorityPoliciesTable, []byte(authorityID))
if nosql.IsErrNotFound(err) {
return nil, admin.NewError(admin.ErrorNotFoundType, "authority policy not found")
} else if err != nil {
return nil, fmt.Errorf("error loading authority policy: %w", err)
}
return data, nil
}
func (db *DB) unmarshalDBAuthorityPolicy(data []byte) (*dbAuthorityPolicy, error) {
if len(data) == 0 {
return nil, nil
}
var dba = new(dbAuthorityPolicy)
if err := json.Unmarshal(data, dba); err != nil {
return nil, fmt.Errorf("error unmarshaling policy bytes into dbAuthorityPolicy: %w", err)
}
return dba, nil
}
func (db *DB) getDBAuthorityPolicy(ctx context.Context, authorityID string) (*dbAuthorityPolicy, error) {
data, err := db.getDBAuthorityPolicyBytes(ctx, authorityID)
if err != nil {
return nil, err
}
dbap, err := db.unmarshalDBAuthorityPolicy(data)
if err != nil {
return nil, err
}
if dbap == nil {
return nil, nil
}
if dbap.AuthorityID != authorityID {
return nil, admin.NewError(admin.ErrorAuthorityMismatchType,
"authority policy is not owned by authority %s", authorityID)
}
return dbap, nil
}
func (db *DB) CreateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
dbap := &dbAuthorityPolicy{
ID: db.authorityID,
AuthorityID: db.authorityID,
Policy: policy,
}
if err := db.save(ctx, dbap.ID, dbap, nil, "authority_policy", authorityPoliciesTable); err != nil {
return admin.WrapErrorISE(err, "error creating authority policy")
}
return nil
}
func (db *DB) GetAuthorityPolicy(ctx context.Context) (*linkedca.Policy, error) {
dbap, err := db.getDBAuthorityPolicy(ctx, db.authorityID)
if err != nil {
return nil, err
}
return dbap.convert(), nil
}
func (db *DB) UpdateAuthorityPolicy(ctx context.Context, policy *linkedca.Policy) error {
old, err := db.getDBAuthorityPolicy(ctx, db.authorityID)
if err != nil {
return err
}
dbap := &dbAuthorityPolicy{
ID: db.authorityID,
AuthorityID: db.authorityID,
Policy: policy,
}
if err := db.save(ctx, dbap.ID, dbap, old, "authority_policy", authorityPoliciesTable); err != nil {
return admin.WrapErrorISE(err, "error updating authority policy")
}
return nil
}
func (db *DB) DeleteAuthorityPolicy(ctx context.Context) error {
old, err := db.getDBAuthorityPolicy(ctx, db.authorityID)
if err != nil {
return err
}
if err := db.save(ctx, old.ID, nil, old, "authority_policy", authorityPoliciesTable); err != nil {
return admin.WrapErrorISE(err, "error deleting authority policy")
}
return nil
}