certificates/authority/admin/db/nosql/policy_test.go

1207 lines
33 KiB
Go
Raw Permalink Normal View History

package nosql
import (
"context"
"encoding/json"
"errors"
"reflect"
"testing"
"github.com/smallstep/assert"
"github.com/smallstep/certificates/authority/admin"
"github.com/smallstep/certificates/db"
"github.com/smallstep/nosql"
nosqldb "github.com/smallstep/nosql/database"
"go.step.sm/linkedca"
)
func TestDB_getDBAuthorityPolicyBytes(t *testing.T) {
authID := "authID"
type test struct {
ctx context.Context
authorityID string
db nosql.DB
err error
adminErr *admin.Error
}
var tests = map[string]func(t *testing.T) test{
"fail/not-found": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, nosqldb.ErrNotFound
},
},
adminErr: admin.NewError(admin.ErrorNotFoundType, "authority policy not found"),
}
},
"fail/db.Get-error": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, errors.New("force")
},
},
err: errors.New("error loading authority policy: force"),
}
},
"ok": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return []byte("foo"), nil
},
},
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
d := DB{db: tc.db}
if b, err := d.getDBAuthorityPolicyBytes(tc.ctx, tc.authorityID); err != nil {
var ae *admin.Error
if errors.As(err, &ae) {
if assert.NotNil(t, tc.adminErr) {
assert.Equals(t, ae.Type, tc.adminErr.Type)
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
assert.Equals(t, ae.Status, tc.adminErr.Status)
assert.Equals(t, ae.Err.Error(), tc.adminErr.Err.Error())
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
}
} else {
if assert.NotNil(t, tc.err) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
}
} else if assert.Nil(t, tc.err) && assert.Nil(t, tc.adminErr) {
assert.Equals(t, string(b), "foo")
}
})
}
}
func TestDB_getDBAuthorityPolicy(t *testing.T) {
authID := "authID"
type test struct {
ctx context.Context
authorityID string
db nosql.DB
err error
adminErr *admin.Error
dbap *dbAuthorityPolicy
}
var tests = map[string]func(t *testing.T) test{
"fail/not-found": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, nosqldb.ErrNotFound
},
},
adminErr: admin.NewError(admin.ErrorNotFoundType, "authority policy not found"),
}
},
"fail/unmarshal-error": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return []byte("foo"), nil
},
},
err: errors.New("error unmarshaling policy bytes into dbAuthorityPolicy"),
}
},
"fail/authorityID-error": func(t *testing.T) test {
dbp := &dbAuthorityPolicy{
ID: "ID",
AuthorityID: "diffAuthID",
Policy: linkedToDB(&linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}),
}
b, err := json.Marshal(dbp)
assert.FatalError(t, err)
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return b, nil
},
},
adminErr: admin.NewError(admin.ErrorAuthorityMismatchType,
"authority policy is not owned by authority authID"),
}
},
"ok/empty-bytes": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return []byte{}, nil
},
},
}
},
"ok": func(t *testing.T) test {
dbap := &dbAuthorityPolicy{
ID: "ID",
AuthorityID: authID,
Policy: linkedToDB(&linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}),
}
b, err := json.Marshal(dbap)
assert.FatalError(t, err)
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return b, nil
},
},
dbap: dbap,
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
d := DB{db: tc.db, authorityID: admin.DefaultAuthorityID}
2022-04-18 19:47:13 +00:00
dbp, err := d.getDBAuthorityPolicy(tc.ctx, tc.authorityID)
switch {
case err != nil:
var ae *admin.Error
if errors.As(err, &ae) {
if assert.NotNil(t, tc.adminErr) {
assert.Equals(t, ae.Type, tc.adminErr.Type)
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
assert.Equals(t, ae.Status, tc.adminErr.Status)
assert.Equals(t, ae.Err.Error(), tc.adminErr.Err.Error())
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
}
} else {
if assert.NotNil(t, tc.err) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
}
2022-04-18 19:47:13 +00:00
case assert.Nil(t, tc.err) && assert.Nil(t, tc.adminErr) && tc.dbap == nil:
assert.Nil(t, dbp)
2022-04-18 19:47:13 +00:00
case assert.Nil(t, tc.err) && assert.Nil(t, tc.adminErr):
assert.Equals(t, dbp.ID, "ID")
assert.Equals(t, dbp.AuthorityID, tc.dbap.AuthorityID)
assert.Equals(t, dbp.Policy, tc.dbap.Policy)
}
})
}
}
func TestDB_CreateAuthorityPolicy(t *testing.T) {
authID := "authID"
type test struct {
ctx context.Context
authorityID string
policy *linkedca.Policy
db nosql.DB
err error
adminErr *admin.Error
}
var tests = map[string]func(t *testing.T) test{
"fail/save-error": func(t *testing.T) test {
policy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
policy: policy,
db: &db.MockNoSQLDB{
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
var _dbap = new(dbAuthorityPolicy)
assert.FatalError(t, json.Unmarshal(nu, _dbap))
assert.Equals(t, _dbap.ID, authID)
assert.Equals(t, _dbap.AuthorityID, authID)
assert.Equals(t, _dbap.Policy, linkedToDB(policy))
return nil, false, errors.New("force")
},
},
adminErr: admin.NewErrorISE("error creating authority policy: error saving authority authority_policy: force"),
}
},
"ok": func(t *testing.T) test {
policy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
policy: policy,
db: &db.MockNoSQLDB{
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, old, nil)
var _dbap = new(dbAuthorityPolicy)
assert.FatalError(t, json.Unmarshal(nu, _dbap))
assert.Equals(t, _dbap.ID, authID)
assert.Equals(t, _dbap.AuthorityID, authID)
assert.Equals(t, _dbap.Policy, linkedToDB(policy))
return nil, true, nil
},
},
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
d := DB{db: tc.db, authorityID: tc.authorityID}
if err := d.CreateAuthorityPolicy(tc.ctx, tc.policy); err != nil {
var ae *admin.Error
if errors.As(err, &ae) {
if assert.NotNil(t, tc.adminErr) {
assert.Equals(t, ae.Type, tc.adminErr.Type)
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
assert.Equals(t, ae.Status, tc.adminErr.Status)
assert.Equals(t, ae.Err.Error(), tc.adminErr.Err.Error())
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
}
} else {
if assert.NotNil(t, tc.err) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
}
}
})
}
}
func TestDB_GetAuthorityPolicy(t *testing.T) {
authID := "authID"
type test struct {
ctx context.Context
authorityID string
policy *linkedca.Policy
db nosql.DB
err error
adminErr *admin.Error
}
var tests = map[string]func(t *testing.T) test{
"fail/not-found": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, nosqldb.ErrNotFound
},
},
adminErr: admin.NewError(admin.ErrorNotFoundType, "authority policy not found"),
}
},
"fail/db.Get-error": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, errors.New("force")
},
},
err: errors.New("error loading authority policy: force"),
}
},
"ok": func(t *testing.T) test {
policy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
policy: policy,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
dbap := &dbAuthorityPolicy{
ID: authID,
AuthorityID: authID,
Policy: linkedToDB(policy),
}
b, err := json.Marshal(dbap)
assert.FatalError(t, err)
return b, nil
},
},
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
d := DB{db: tc.db, authorityID: tc.authorityID}
got, err := d.GetAuthorityPolicy(tc.ctx)
if err != nil {
var ae *admin.Error
if errors.As(err, &ae) {
if assert.NotNil(t, tc.adminErr) {
assert.Equals(t, ae.Type, tc.adminErr.Type)
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
assert.Equals(t, ae.Status, tc.adminErr.Status)
assert.Equals(t, ae.Err.Error(), tc.adminErr.Err.Error())
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
}
} else {
if assert.NotNil(t, tc.err) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
}
return
}
assert.NotNil(t, got)
assert.Equals(t, tc.policy, got)
})
}
}
func TestDB_UpdateAuthorityPolicy(t *testing.T) {
authID := "authID"
type test struct {
ctx context.Context
authorityID string
policy *linkedca.Policy
db nosql.DB
err error
adminErr *admin.Error
}
var tests = map[string]func(t *testing.T) test{
"fail/not-found": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, nosqldb.ErrNotFound
},
},
adminErr: admin.NewError(admin.ErrorNotFoundType, "authority policy not found"),
}
},
"fail/db.Get-error": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, errors.New("force")
},
},
err: errors.New("error loading authority policy: force"),
}
},
"fail/save-error": func(t *testing.T) test {
oldPolicy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.localhost"},
},
},
}
policy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
policy: policy,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
dbap := &dbAuthorityPolicy{
ID: authID,
AuthorityID: authID,
Policy: linkedToDB(oldPolicy),
}
b, err := json.Marshal(dbap)
assert.FatalError(t, err)
return b, nil
},
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
var _dbap = new(dbAuthorityPolicy)
assert.FatalError(t, json.Unmarshal(nu, _dbap))
assert.Equals(t, _dbap.ID, authID)
assert.Equals(t, _dbap.AuthorityID, authID)
assert.Equals(t, _dbap.Policy, linkedToDB(policy))
return nil, false, errors.New("force")
},
},
adminErr: admin.NewErrorISE("error updating authority policy: error saving authority authority_policy: force"),
}
},
"ok": func(t *testing.T) test {
oldPolicy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.localhost"},
},
},
}
policy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
policy: policy,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
dbap := &dbAuthorityPolicy{
ID: authID,
AuthorityID: authID,
Policy: linkedToDB(oldPolicy),
}
b, err := json.Marshal(dbap)
assert.FatalError(t, err)
return b, nil
},
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
var _dbap = new(dbAuthorityPolicy)
assert.FatalError(t, json.Unmarshal(nu, _dbap))
assert.Equals(t, _dbap.ID, authID)
assert.Equals(t, _dbap.AuthorityID, authID)
assert.Equals(t, _dbap.Policy, linkedToDB(policy))
return nil, true, nil
},
},
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
d := DB{db: tc.db, authorityID: tc.authorityID}
if err := d.UpdateAuthorityPolicy(tc.ctx, tc.policy); err != nil {
var ae *admin.Error
if errors.As(err, &ae) {
if assert.NotNil(t, tc.adminErr) {
assert.Equals(t, ae.Type, tc.adminErr.Type)
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
assert.Equals(t, ae.Status, tc.adminErr.Status)
assert.Equals(t, ae.Err.Error(), tc.adminErr.Err.Error())
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
}
} else {
if assert.NotNil(t, tc.err) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
}
return
}
})
}
}
func TestDB_DeleteAuthorityPolicy(t *testing.T) {
authID := "authID"
type test struct {
ctx context.Context
authorityID string
db nosql.DB
err error
adminErr *admin.Error
}
var tests = map[string]func(t *testing.T) test{
"fail/not-found": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, nosqldb.ErrNotFound
},
},
adminErr: admin.NewError(admin.ErrorNotFoundType, "authority policy not found"),
}
},
"fail/db.Get-error": func(t *testing.T) test {
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
return nil, errors.New("force")
},
},
err: errors.New("error loading authority policy: force"),
}
},
"fail/save-error": func(t *testing.T) test {
oldPolicy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.localhost"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
dbap := &dbAuthorityPolicy{
ID: authID,
AuthorityID: authID,
Policy: linkedToDB(oldPolicy),
}
b, err := json.Marshal(dbap)
assert.FatalError(t, err)
return b, nil
},
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
assert.Equals(t, nil, nu)
return nil, false, errors.New("force")
},
},
adminErr: admin.NewErrorISE("error deleting authority policy: error saving authority authority_policy: force"),
}
},
"ok": func(t *testing.T) test {
oldPolicy := &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.localhost"},
},
},
}
return test{
ctx: context.Background(),
authorityID: authID,
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
dbap := &dbAuthorityPolicy{
ID: authID,
AuthorityID: authID,
Policy: linkedToDB(oldPolicy),
}
b, err := json.Marshal(dbap)
assert.FatalError(t, err)
return b, nil
},
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, authorityPoliciesTable)
assert.Equals(t, string(key), authID)
assert.Equals(t, nil, nu)
return nil, true, nil
},
},
}
},
}
for name, run := range tests {
tc := run(t)
t.Run(name, func(t *testing.T) {
d := DB{db: tc.db, authorityID: tc.authorityID}
if err := d.DeleteAuthorityPolicy(tc.ctx); err != nil {
var ae *admin.Error
if errors.As(err, &ae) {
if assert.NotNil(t, tc.adminErr) {
assert.Equals(t, ae.Type, tc.adminErr.Type)
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
assert.Equals(t, ae.Status, tc.adminErr.Status)
assert.Equals(t, ae.Err.Error(), tc.adminErr.Err.Error())
assert.Equals(t, ae.Detail, tc.adminErr.Detail)
}
} else {
if assert.NotNil(t, tc.err) {
assert.HasPrefix(t, err.Error(), tc.err.Error())
}
}
return
}
})
}
}
func Test_linkedToDB(t *testing.T) {
type args struct {
p *linkedca.Policy
}
tests := []struct {
name string
args args
want *dbPolicy
}{
{
name: "nil policy",
args: args{
p: nil,
},
want: nil,
},
{
name: "no x509 nor ssh",
args: args{
p: &linkedca.Policy{},
},
want: nil,
},
{
name: "x509",
args: args{
p: &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Emails: []string{"@example.com"},
Uris: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &linkedca.X509Names{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Emails: []string{"root@example.com"},
Uris: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
},
},
want: &dbPolicy{
X509: &dbX509Policy{
Allow: &dbX509Names{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
EmailAddresses: []string{"@example.com"},
URIDomains: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &dbX509Names{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
EmailAddresses: []string{"root@example.com"},
URIDomains: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
},
},
{
name: "ssh user",
args: args{
p: &linkedca.Policy{
Ssh: &linkedca.SSHPolicy{
User: &linkedca.SSHUserPolicy{
Allow: &linkedca.SSHUserNames{
Emails: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &linkedca.SSHUserNames{
Emails: []string{"root@example.com"},
Principals: []string{"root"},
},
},
},
},
},
want: &dbPolicy{
SSH: &dbSSHPolicy{
User: &dbSSHUserPolicy{
Allow: &dbSSHUserNames{
EmailAddresses: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &dbSSHUserNames{
EmailAddresses: []string{"root@example.com"},
Principals: []string{"root"},
},
},
},
},
},
{
name: "full ssh policy",
args: args{
p: &linkedca.Policy{
Ssh: &linkedca.SSHPolicy{
Host: &linkedca.SSHHostPolicy{
Allow: &linkedca.SSHHostNames{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &linkedca.SSHHostNames{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
want: &dbPolicy{
SSH: &dbSSHPolicy{
Host: &dbSSHHostPolicy{
Allow: &dbSSHHostNames{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &dbSSHHostNames{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
{
name: "full policy",
args: args{
p: &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Emails: []string{"@example.com"},
Uris: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &linkedca.X509Names{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Emails: []string{"root@example.com"},
Uris: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
Ssh: &linkedca.SSHPolicy{
User: &linkedca.SSHUserPolicy{
Allow: &linkedca.SSHUserNames{
Emails: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &linkedca.SSHUserNames{
Emails: []string{"root@example.com"},
Principals: []string{"root"},
},
},
Host: &linkedca.SSHHostPolicy{
Allow: &linkedca.SSHHostNames{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &linkedca.SSHHostNames{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
want: &dbPolicy{
X509: &dbX509Policy{
Allow: &dbX509Names{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
EmailAddresses: []string{"@example.com"},
URIDomains: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &dbX509Names{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
EmailAddresses: []string{"root@example.com"},
URIDomains: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
SSH: &dbSSHPolicy{
User: &dbSSHUserPolicy{
Allow: &dbSSHUserNames{
EmailAddresses: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &dbSSHUserNames{
EmailAddresses: []string{"root@example.com"},
Principals: []string{"root"},
},
},
Host: &dbSSHHostPolicy{
Allow: &dbSSHHostNames{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &dbSSHHostNames{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := linkedToDB(tt.args.p); !reflect.DeepEqual(got, tt.want) {
t.Errorf("linkedToDB() = %v, want %v", got, tt.want)
}
})
}
}
func Test_dbToLinked(t *testing.T) {
type args struct {
p *dbPolicy
}
tests := []struct {
name string
args args
want *linkedca.Policy
}{
{
name: "nil policy",
args: args{
p: nil,
},
want: nil,
},
{
name: "x509",
args: args{
p: &dbPolicy{
X509: &dbX509Policy{
Allow: &dbX509Names{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
EmailAddresses: []string{"@example.com"},
URIDomains: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &dbX509Names{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
EmailAddresses: []string{"root@example.com"},
URIDomains: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
},
},
want: &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Emails: []string{"@example.com"},
Uris: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &linkedca.X509Names{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Emails: []string{"root@example.com"},
Uris: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
},
},
{
name: "ssh user",
args: args{
p: &dbPolicy{
SSH: &dbSSHPolicy{
User: &dbSSHUserPolicy{
Allow: &dbSSHUserNames{
EmailAddresses: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &dbSSHUserNames{
EmailAddresses: []string{"root@example.com"},
Principals: []string{"root"},
},
},
},
},
},
want: &linkedca.Policy{
Ssh: &linkedca.SSHPolicy{
User: &linkedca.SSHUserPolicy{
Allow: &linkedca.SSHUserNames{
Emails: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &linkedca.SSHUserNames{
Emails: []string{"root@example.com"},
Principals: []string{"root"},
},
},
},
},
},
{
name: "ssh host",
args: args{
p: &dbPolicy{
SSH: &dbSSHPolicy{
Host: &dbSSHHostPolicy{
Allow: &dbSSHHostNames{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &dbSSHHostNames{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
want: &linkedca.Policy{
Ssh: &linkedca.SSHPolicy{
Host: &linkedca.SSHHostPolicy{
Allow: &linkedca.SSHHostNames{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &linkedca.SSHHostNames{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
{
name: "full policy",
args: args{
p: &dbPolicy{
X509: &dbX509Policy{
Allow: &dbX509Names{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
EmailAddresses: []string{"@example.com"},
URIDomains: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &dbX509Names{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
EmailAddresses: []string{"root@example.com"},
URIDomains: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
SSH: &dbSSHPolicy{
User: &dbSSHUserPolicy{
Allow: &dbSSHUserNames{
EmailAddresses: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &dbSSHUserNames{
EmailAddresses: []string{"root@example.com"},
Principals: []string{"root"},
},
},
Host: &dbSSHHostPolicy{
Allow: &dbSSHHostNames{
DNSDomains: []string{"*.local"},
IPRanges: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &dbSSHHostNames{
DNSDomains: []string{"badhost.local"},
IPRanges: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
want: &linkedca.Policy{
X509: &linkedca.X509Policy{
Allow: &linkedca.X509Names{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Emails: []string{"@example.com"},
Uris: []string{"*.example.com"},
CommonNames: []string{"some name"},
},
Deny: &linkedca.X509Names{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Emails: []string{"root@example.com"},
Uris: []string{"bad.example.com"},
CommonNames: []string{"bad name"},
},
AllowWildcardNames: true,
},
Ssh: &linkedca.SSHPolicy{
User: &linkedca.SSHUserPolicy{
Allow: &linkedca.SSHUserNames{
Emails: []string{"@example.com"},
Principals: []string{"user"},
},
Deny: &linkedca.SSHUserNames{
Emails: []string{"root@example.com"},
Principals: []string{"root"},
},
},
Host: &linkedca.SSHHostPolicy{
Allow: &linkedca.SSHHostNames{
Dns: []string{"*.local"},
Ips: []string{"192.168.0.1/24"},
Principals: []string{"host"},
},
Deny: &linkedca.SSHHostNames{
Dns: []string{"badhost.local"},
Ips: []string{"192.168.0.30"},
Principals: []string{"bad"},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := dbToLinked(tt.args.p); !reflect.DeepEqual(got, tt.want) {
t.Errorf("dbToLinked() = %v, want %v", got, tt.want)
}
})
}
}