certificates/authority/mgmt/db/nosql/authConfig.go
max furman 4f3e5ef64d wip
2021-05-19 15:20:16 -07:00

117 lines
2.9 KiB
Go

package nosql
import (
"context"
"encoding/json"
"time"
"github.com/pkg/errors"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/mgmt"
"github.com/smallstep/certificates/authority/status"
"github.com/smallstep/nosql"
)
type dbAuthConfig struct {
ID string `json:"id"`
ASN1DN *config.ASN1DN `json:"asn1dn"`
Claims *mgmt.Claims `json:"claims"`
Backdate string `json:"backdate,omitempty"`
CreatedAt time.Time `json:"createdAt"`
DeletedAt time.Time `json:"deletedAt"`
}
func (dbp *dbAuthConfig) clone() *dbAuthConfig {
u := *dbp
return &u
}
func (db *DB) getDBAuthConfigBytes(ctx context.Context, id string) ([]byte, error) {
data, err := db.db.Get(authorityConfigsTable, []byte(id))
if nosql.IsErrNotFound(err) {
return nil, mgmt.NewError(mgmt.ErrorNotFoundType, "authConfig %s not found", id)
} else if err != nil {
return nil, errors.Wrapf(err, "error loading authConfig %s", id)
}
return data, nil
}
func (db *DB) getDBAuthConfig(ctx context.Context, id string) (*dbAuthConfig, error) {
data, err := db.getDBAuthConfigBytes(ctx, id)
if err != nil {
return nil, err
}
var dba = new(dbAuthConfig)
if err = json.Unmarshal(data, dba); err != nil {
return nil, errors.Wrapf(err, "error unmarshaling authority %s into dbAuthConfig", id)
}
return dba, nil
}
// GetAuthConfig retrieves an AuthConfig configuration from the DB.
func (db *DB) GetAuthConfig(ctx context.Context, id string) (*mgmt.AuthConfig, error) {
dba, err := db.getDBAuthConfig(ctx, id)
if err != nil {
return nil, err
}
provs, err := db.GetProvisioners(ctx)
if err != nil {
return nil, err
}
admins, err := db.GetAdmins(ctx)
if err != nil {
return nil, err
}
return &mgmt.AuthConfig{
ID: dba.ID,
Admins: admins,
Provisioners: provs,
ASN1DN: dba.ASN1DN,
Backdate: dba.Backdate,
Claims: dba.Claims,
}, nil
}
// CreateAuthConfig stores a new provisioner to the database.
func (db *DB) CreateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
var err error
if ac.ID == "" {
ac.ID, err = randID()
if err != nil {
return errors.Wrap(err, "error generating random id for provisioner")
}
}
dba := &dbAuthConfig{
ID: ac.ID,
ASN1DN: ac.ASN1DN,
Claims: ac.Claims,
Backdate: ac.Backdate,
CreatedAt: clock.Now(),
}
return db.save(ctx, dba.ID, dba, nil, "authConfig", authorityConfigsTable)
}
// UpdateAuthConfig saves an updated provisioner to the database.
func (db *DB) UpdateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
old, err := db.getDBAuthConfig(ctx, ac.ID)
if err != nil {
return err
}
nu := old.clone()
// If the authority was active but is now deleted ...
if old.DeletedAt.IsZero() && ac.Status == status.Deleted {
nu.DeletedAt = clock.Now()
}
nu.Claims = ac.Claims
nu.Backdate = ac.Backdate
return db.save(ctx, old.ID, nu, old, "authConfig", authorityProvisionersTable)
}