Switch to real model vs. view
This commit is contained in:
parent
015e089b7d
commit
69edf779b5
|
|
@ -21,7 +21,7 @@ CREATE TABLE `registrations` (
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `authz` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`id` varchar(43) NOT NULL,
|
||||
`identifier` varchar(255) DEFAULT NULL,
|
||||
`registrationID` bigint(20) DEFAULT NULL,
|
||||
`status` varchar(255) DEFAULT NULL,
|
||||
|
|
@ -59,11 +59,11 @@ CREATE TABLE `certificateStatus` (
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `challenges` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`authorizationID` char(43) NOT NULL,
|
||||
`LockCol` bigint(20) DEFAULT NULL,
|
||||
`type` varchar(255) NOT NULL,
|
||||
`status` varchar(255) DEFAULT NULL,
|
||||
`status` varchar(255) NOT NULL,
|
||||
`error` varchar(255) DEFAULT NULL,
|
||||
`validated` datetime DEFAULT NULL,
|
||||
`uri` varchar(255) DEFAULT NULL,
|
||||
|
|
@ -96,7 +96,7 @@ CREATE TABLE `ocspResponses` (
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `pending_authz` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`id` varchar(43) NOT NULL,
|
||||
`identifier` varchar(255) DEFAULT NULL,
|
||||
`registrationID` bigint(20) DEFAULT NULL,
|
||||
`status` varchar(255) DEFAULT NULL,
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ func initTables(dbMap *gorp.DbMap) {
|
|||
pendingAuthzTable := dbMap.AddTableWithName(pendingauthzModel{}, "pending_authz").SetKeys(false, "ID")
|
||||
pendingAuthzTable.SetVersionCol("LockCol")
|
||||
dbMap.AddTableWithName(authzModel{}, "authz").SetKeys(false, "ID")
|
||||
dbMap.AddTableWithName(challengeModel{}, "challenges").SetKeys(true, "ID").SetVersionCol("LockCol")
|
||||
dbMap.AddTableWithName(challModel{}, "challenges").SetKeys(true, "ID").SetVersionCol("LockCol")
|
||||
dbMap.AddTableWithName(core.Certificate{}, "certificates").SetKeys(false, "Serial")
|
||||
dbMap.AddTableWithName(core.CertificateStatus{}, "certificateStatus").SetKeys(false, "Serial").SetVersionCol("LockCol")
|
||||
dbMap.AddTableWithName(core.OCSPResponse{}, "ocspResponses").SetKeys(true, "ID")
|
||||
|
|
|
|||
77
sa/model.go
77
sa/model.go
|
|
@ -3,6 +3,8 @@ package sa
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
|
|
@ -18,6 +20,23 @@ type regModel struct {
|
|||
LockCol int64
|
||||
}
|
||||
|
||||
// challModel is the description of a core.Challenge in the database
|
||||
type challModel struct {
|
||||
ID int64 `db:"id"`
|
||||
AuthorizationID string `db:"authorizationID"`
|
||||
|
||||
Type string `db:"type"`
|
||||
Status core.AcmeStatus `db:"status"`
|
||||
Error []byte `db:"error"`
|
||||
Validated *time.Time `db:"validated"`
|
||||
URI *core.AcmeURL `db:"uri"`
|
||||
Token string `db:"token"`
|
||||
TLS *bool `db:"tls"`
|
||||
Validation []byte `db:"validation"`
|
||||
|
||||
LockCol int64
|
||||
}
|
||||
|
||||
// newReg creates a reg model object from a core.Registration
|
||||
func registrationToModel(r *core.Registration) (*regModel, error) {
|
||||
key, err := json.Marshal(r.Key)
|
||||
|
|
@ -54,3 +73,61 @@ func modelToRegistration(rm *regModel) (core.Registration, error) {
|
|||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func challengeToModel(c *core.Challenge, authID string) (*challModel, error) {
|
||||
cm := challModel{
|
||||
AuthorizationID: authID,
|
||||
Type: c.Type,
|
||||
Status: c.Status,
|
||||
Validated: c.Validated,
|
||||
URI: c.URI,
|
||||
Token: c.Token,
|
||||
TLS: c.TLS,
|
||||
// Validation: []byte(c.Validation.FullSerialize()),
|
||||
}
|
||||
if c.Validation != nil {
|
||||
cm.Validation = []byte(c.Validation.FullSerialize())
|
||||
if len(cm.Validation) > int(math.Pow(2, 24)) {
|
||||
return nil, fmt.Errorf("Validation object is too large to store in the database")
|
||||
}
|
||||
}
|
||||
if c.Error != nil {
|
||||
errJSON, err := json.Marshal(c.Error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cm.Error = errJSON
|
||||
}
|
||||
if cm.URI != nil && len(cm.URI.String()) > 255 {
|
||||
return nil, fmt.Errorf("URI is too long")
|
||||
}
|
||||
return &cm, nil
|
||||
}
|
||||
|
||||
func modelToChallenge(cm *challModel) (core.Challenge, error) {
|
||||
var val *jose.JsonWebSignature
|
||||
var problem core.ProblemDetails
|
||||
var err error
|
||||
if len(cm.Validation) > 0 {
|
||||
val, err = jose.ParseSigned(string(cm.Validation))
|
||||
if err != nil {
|
||||
return core.Challenge{}, err
|
||||
}
|
||||
}
|
||||
if len(cm.Error) > 0 {
|
||||
err := json.Unmarshal(cm.Error, &problem)
|
||||
if err != nil {
|
||||
return core.Challenge{}, err
|
||||
}
|
||||
}
|
||||
return core.Challenge{
|
||||
Type: cm.Type,
|
||||
Status: cm.Status,
|
||||
Error: &problem,
|
||||
Validated: cm.Validated,
|
||||
URI: cm.URI,
|
||||
Token: cm.Token,
|
||||
TLS: cm.TLS,
|
||||
Validation: val,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,14 +47,6 @@ type authzModel struct {
|
|||
Sequence int64 `db:"sequence"`
|
||||
}
|
||||
|
||||
type challengeModel struct {
|
||||
ID int `json:"id,omitempty" db:"id"`
|
||||
AuthorizationID string `json:"authorizationID,omitempty" db:"authorizationID"`
|
||||
LockCol int64
|
||||
|
||||
core.Challenge
|
||||
}
|
||||
|
||||
// NewSQLStorageAuthority provides persistence using a SQL backend for
|
||||
// Boulder. It will modify the given gorp.DbMap by adding relevent tables.
|
||||
func NewSQLStorageAuthority(dbMap *gorp.DbMap) (*SQLStorageAuthority, error) {
|
||||
|
|
@ -178,7 +170,7 @@ func (ssa *SQLStorageAuthority) GetAuthorization(id string) (authz core.Authoriz
|
|||
authz = authD.Authorization
|
||||
}
|
||||
|
||||
var challObjs []challengeModel
|
||||
var challObjs []challModel
|
||||
_, err = tx.Select(&challObjs, "SELECT * FROM challenges WHERE authorizationID = :authID", map[string]interface{}{"authID": authz.ID})
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
|
|
@ -186,7 +178,12 @@ func (ssa *SQLStorageAuthority) GetAuthorization(id string) (authz core.Authoriz
|
|||
}
|
||||
var challs []core.Challenge
|
||||
for _, c := range challObjs {
|
||||
challs = append(challs, c.Challenge)
|
||||
chall, err := modelToChallenge(&c)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return core.Authorization{}, err
|
||||
}
|
||||
challs = append(challs, chall)
|
||||
}
|
||||
authz.Challenges = challs
|
||||
|
||||
|
|
@ -209,13 +206,17 @@ func (ssa *SQLStorageAuthority) GetLatestValidAuthorization(registrationId int64
|
|||
return
|
||||
}
|
||||
|
||||
var challObjs []challengeModel
|
||||
var challObjs []challModel
|
||||
_, err = ssa.dbMap.Select(&challObjs, "SELECT * FROM challenges WHERE authorizationID = :authID", map[string]interface{}{"authID": authz.ID})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, c := range challObjs {
|
||||
authz.Challenges = append(authz.Challenges, c.Challenge)
|
||||
chall, err := modelToChallenge(&c)
|
||||
if err != nil {
|
||||
return core.Authorization{}, err
|
||||
}
|
||||
authz.Challenges = append(authz.Challenges, chall)
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -418,14 +419,15 @@ func (ssa *SQLStorageAuthority) NewPendingAuthorization(authz core.Authorization
|
|||
}
|
||||
|
||||
for _, c := range authz.Challenges {
|
||||
chall := challengeModel{
|
||||
AuthorizationID: pendingAuthz.ID,
|
||||
Challenge: c,
|
||||
}
|
||||
err = tx.Insert(&chall)
|
||||
chall, err := challengeToModel(&c, pendingAuthz.ID)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return
|
||||
return core.Authorization{}, err
|
||||
}
|
||||
err = tx.Insert(chall)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return core.Authorization{}, err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -473,7 +475,7 @@ func (ssa *SQLStorageAuthority) UpdatePendingAuthorization(authz core.Authorizat
|
|||
return
|
||||
}
|
||||
|
||||
var challs []challengeModel
|
||||
var challs []challModel
|
||||
_, err = tx.Select(
|
||||
&challs,
|
||||
"SELECT * FROM challenges WHERE authorizationID = :authID",
|
||||
|
|
@ -487,15 +489,13 @@ func (ssa *SQLStorageAuthority) UpdatePendingAuthorization(authz core.Authorizat
|
|||
return fmt.Errorf("Invalid number of challenges provided")
|
||||
}
|
||||
for i, authChall := range authz.Challenges {
|
||||
chall := challengeModel{
|
||||
ID: challs[i].ID,
|
||||
Challenge: authChall,
|
||||
AuthorizationID: challs[i].AuthorizationID,
|
||||
chall, err := challengeToModel(&authChall, challs[i].AuthorizationID)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
chall.Challenge = authChall
|
||||
chall.ID = challs[i].ID
|
||||
chall.AuthorizationID = challs[i].AuthorizationID
|
||||
_, err = tx.Update(&chall)
|
||||
_, err = tx.Update(chall)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
|
|
@ -557,7 +557,7 @@ func (ssa *SQLStorageAuthority) FinalizeAuthorization(authz core.Authorization)
|
|||
return
|
||||
}
|
||||
|
||||
var challs []challengeModel
|
||||
var challs []challModel
|
||||
_, err = tx.Select(
|
||||
&challs,
|
||||
"SELECT * FROM challenges WHERE authorizationID = :authID",
|
||||
|
|
@ -571,12 +571,13 @@ func (ssa *SQLStorageAuthority) FinalizeAuthorization(authz core.Authorization)
|
|||
return fmt.Errorf("Invalid number of challenges provided")
|
||||
}
|
||||
for i, authChall := range authz.Challenges {
|
||||
chall := challengeModel{
|
||||
Challenge: authChall,
|
||||
ID: challs[i].ID,
|
||||
AuthorizationID: challs[i].AuthorizationID,
|
||||
chall, err := challengeToModel(&authChall, challs[i].AuthorizationID)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
_, err = tx.Update(&chall)
|
||||
chall.ID = challs[i].ID
|
||||
_, err = tx.Update(chall)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -43,11 +43,6 @@ func (tc BoulderTypeConverter) ToDb(val interface{}) (interface{}, error) {
|
|||
return t.String(), nil
|
||||
}
|
||||
return "", nil
|
||||
case *jose.JsonWebSignature:
|
||||
if t != nil {
|
||||
return []byte(t.FullSerialize()), nil
|
||||
}
|
||||
return []byte{}, nil
|
||||
default:
|
||||
return val, nil
|
||||
}
|
||||
|
|
@ -84,26 +79,6 @@ func (tc BoulderTypeConverter) FromDb(target interface{}) (gorp.CustomScanner, b
|
|||
return nil
|
||||
}
|
||||
return gorp.CustomScanner{Holder: new(string), Target: target, Binder: binder}, true
|
||||
case **jose.JsonWebSignature:
|
||||
binder := func(holder, target interface{}) error {
|
||||
s, ok := holder.(*[]byte)
|
||||
if !ok {
|
||||
return errors.New("FromDb: Unable to convert *string")
|
||||
}
|
||||
st, ok := target.(**jose.JsonWebSignature)
|
||||
if !ok {
|
||||
return fmt.Errorf("FromDb: Unable to convert %T to **jose.JsonWebSignature", target)
|
||||
}
|
||||
if len(*s) != 0 {
|
||||
sig, err := jose.ParseSigned(string(*s))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*st = &(*sig)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return gorp.CustomScanner{Holder: new([]byte), Target: target, Binder: binder}, true
|
||||
case *jose.JsonWebKey:
|
||||
binder := func(holder, target interface{}) error {
|
||||
s, ok := holder.(*string)
|
||||
|
|
|
|||
|
|
@ -185,29 +185,3 @@ func TestAcmeURL(t *testing.T) {
|
|||
err = scanner.Binder(&marshaled, &out)
|
||||
test.AssertMarshaledEquals(t, au, out)
|
||||
}
|
||||
|
||||
func TestJsonWebSignature(t *testing.T) {
|
||||
tc := BoulderTypeConverter{}
|
||||
|
||||
var out *jose.JsonWebSignature
|
||||
validationPayload, _ := json.Marshal(map[string]interface{}{
|
||||
"type": "type",
|
||||
"token": "token",
|
||||
})
|
||||
signer, _ := jose.NewSigner(jose.RS256, &TheKey)
|
||||
jws, _ := signer.Sign(validationPayload, "")
|
||||
|
||||
marshaledI, err := tc.ToDb(jws)
|
||||
test.AssertNotError(t, err, "Could not ToDb")
|
||||
|
||||
scanner, ok := tc.FromDb(&out)
|
||||
test.Assert(t, ok, "FromDb failed")
|
||||
if !ok {
|
||||
t.FailNow()
|
||||
return
|
||||
}
|
||||
|
||||
marshaled := marshaledI.([]byte)
|
||||
err = scanner.Binder(&marshaled, &out)
|
||||
test.AssertMarshaledEquals(t, jws, out)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue