// UpdateRegistration stores an updated Registration func (ssa *SQLStorageAuthority) UpdateRegistration(reg core.Registration) error { lookupResult, err := ssa.dbMap.Get(regModel{}, reg.ID) if err != nil { return err } if lookupResult == nil { msg := fmt.Sprintf("No registrations with ID %d", reg.ID) return core.NoSuchRegistrationError(msg) } existingRegModel, ok := lookupResult.(*regModel) if !ok { // Shouldn't happen return fmt.Errorf("Incorrect type returned from registration lookup") } updatedRegModel, err := registrationToModel(®) if err != nil { return err } updatedRegModel.LockCol = existingRegModel.LockCol n, err := ssa.dbMap.Update(updatedRegModel) if err != nil { return err } if n == 0 { msg := fmt.Sprintf("Requested registration not found %d", reg.ID) return core.NoSuchRegistrationError(msg) } return nil }
func unwrapError(err error) error { code := grpc.Code(err) errBody := grpc.ErrorDesc(err) switch code { case InternalServerError: return core.InternalServerError(errBody) case NotSupportedError: return core.NotSupportedError(errBody) case MalformedRequestError: return core.MalformedRequestError(errBody) case UnauthorizedError: return core.UnauthorizedError(errBody) case NotFoundError: return core.NotFoundError(errBody) case SignatureValidationError: return core.SignatureValidationError(errBody) case NoSuchRegistrationError: return core.NoSuchRegistrationError(errBody) case RateLimitedError: return core.RateLimitedError(errBody) case LengthRequiredError: return core.LengthRequiredError(errBody) case BadNonceError: return core.BadNonceError(errBody) default: return err } }
// GetRegistrationByKey obtains a Registration by JWK func (ssa *SQLStorageAuthority) GetRegistrationByKey(ctx context.Context, key *jose.JsonWebKey) (core.Registration, error) { const query = "WHERE jwk_sha256 = ?" var model interface{} var err error if key == nil { return core.Registration{}, fmt.Errorf("key argument to GetRegistrationByKey must not be nil") } sha, err := core.KeyDigest(key.Key) if err != nil { return core.Registration{}, err } if features.Enabled(features.AllowAccountDeactivation) { model, err = selectRegistrationv2(ssa.dbMap, query, sha) } else { model, err = selectRegistration(ssa.dbMap, query, sha) } if err == sql.ErrNoRows { msg := fmt.Sprintf("No registrations with public key sha256 %s", sha) return core.Registration{}, core.NoSuchRegistrationError(msg) } if err != nil { return core.Registration{}, err } return modelToRegistration(model) }
// Unwraps a rpcError and returns the correct error type. func unwrapError(rpcError *rpcError) error { if rpcError != nil { switch rpcError.Type { case "InternalServerError": return core.InternalServerError(rpcError.Value) case "NotSupportedError": return core.NotSupportedError(rpcError.Value) case "MalformedRequestError": return core.MalformedRequestError(rpcError.Value) case "UnauthorizedError": return core.UnauthorizedError(rpcError.Value) case "NotFoundError": return core.NotFoundError(rpcError.Value) case "SyntaxError": return core.SyntaxError(rpcError.Value) case "SignatureValidationError": return core.SignatureValidationError(rpcError.Value) case "CertificateIssuanceError": return core.CertificateIssuanceError(rpcError.Value) case "NoSuchRegistrationError": return core.NoSuchRegistrationError(rpcError.Value) case "TooManyRPCRequestsError": return core.TooManyRPCRequestsError(rpcError.Value) case "RateLimitedError": return core.RateLimitedError(rpcError.Value) case "ServiceUnavailableError": return core.ServiceUnavailableError(rpcError.Value) default: return errors.New(rpcError.Value) } } return nil }
// Unwraps a rpcError and returns the correct error type. func unwrapError(rpcError *rpcError) error { if rpcError != nil { switch rpcError.Type { case "InternalServerError": return core.InternalServerError(rpcError.Value) case "NotSupportedError": return core.NotSupportedError(rpcError.Value) case "MalformedRequestError": return core.MalformedRequestError(rpcError.Value) case "UnauthorizedError": return core.UnauthorizedError(rpcError.Value) case "NotFoundError": return core.NotFoundError(rpcError.Value) case "SignatureValidationError": return core.SignatureValidationError(rpcError.Value) case "NoSuchRegistrationError": return core.NoSuchRegistrationError(rpcError.Value) case "TooManyRPCRequestsError": return core.TooManyRPCRequestsError(rpcError.Value) case "RateLimitedError": return core.RateLimitedError(rpcError.Value) default: if strings.HasPrefix(rpcError.Type, "urn:") { return &probs.ProblemDetails{ Type: probs.ProblemType(rpcError.Type), Detail: rpcError.Value, HTTPStatus: rpcError.HTTPStatus, } } return errors.New(rpcError.Value) } } return nil }
// Unwraps a rpcError and returns the correct error type. func unwrapError(rpcError rpcError) (err error) { if rpcError.Value != "" { switch rpcError.Type { case "InternalServerError": err = core.InternalServerError(rpcError.Value) case "NotSupportedError": err = core.NotSupportedError(rpcError.Value) case "MalformedRequestError": err = core.MalformedRequestError(rpcError.Value) case "UnauthorizedError": err = core.UnauthorizedError(rpcError.Value) case "NotFoundError": err = core.NotFoundError(rpcError.Value) case "SyntaxError": err = core.SyntaxError(rpcError.Value) case "SignatureValidationError": err = core.SignatureValidationError(rpcError.Value) case "CertificateIssuanceError": err = core.CertificateIssuanceError(rpcError.Value) case "NoSuchRegistrationError": err = core.NoSuchRegistrationError(rpcError.Value) case "TooManyRPCRequestsError": err = core.TooManyRPCRequestsError(rpcError.Value) case "RateLimitedError": err = core.RateLimitedError(rpcError.Value) default: err = errors.New(rpcError.Value) } } return }
func (f fakeRegStore) GetRegistration(id int64) (core.Registration, error) { r, ok := f.RegByID[id] if !ok { msg := fmt.Sprintf("no such registration %d", id) return r, core.NoSuchRegistrationError(msg) } return r, nil }
// UpdateRegistration stores an updated Registration func (ssa *SQLStorageAuthority) UpdateRegistration(ctx context.Context, reg core.Registration) error { const query = "WHERE id = ?" var model interface{} var err error if features.Enabled(features.AllowAccountDeactivation) { model, err = selectRegistrationv2(ssa.dbMap, query, reg.ID) } else { model, err = selectRegistration(ssa.dbMap, query, reg.ID) } if err == sql.ErrNoRows { msg := fmt.Sprintf("No registrations with ID %d", reg.ID) return core.NoSuchRegistrationError(msg) } updatedRegModel, err := registrationToModel(®) if err != nil { return err } // Since registrationToModel has to return an interface so that we can use either model // version we need to cast both the updated and existing model to their proper types // so that we can copy over the LockCol from one to the other. Once we have copied // that field we reassign to the interface so gorp can properly update it. if features.Enabled(features.AllowAccountDeactivation) { erm := model.(*regModelv2) urm := updatedRegModel.(*regModelv2) urm.LockCol = erm.LockCol updatedRegModel = urm } else { erm := model.(*regModelv1) urm := updatedRegModel.(*regModelv1) urm.LockCol = erm.LockCol updatedRegModel = urm } n, err := ssa.dbMap.Update(updatedRegModel) if err != nil { return err } if n == 0 { msg := fmt.Sprintf("Requested registration not found %d", reg.ID) return core.NoSuchRegistrationError(msg) } return nil }
func TestWrapError(t *testing.T) { testCases := []error{ core.InternalServerError("foo"), core.NotSupportedError("foo"), core.MalformedRequestError("foo"), core.UnauthorizedError("foo"), core.NotFoundError("foo"), core.SignatureValidationError("foo"), core.CertificateIssuanceError("foo"), core.NoSuchRegistrationError("foo"), core.RateLimitedError("foo"), core.TooManyRPCRequestsError("foo"), errors.New("foo"), } for _, c := range testCases { wrapped := wrapError(c) test.AssertEquals(t, wrapped.Type, reflect.TypeOf(c).Name()) test.AssertEquals(t, wrapped.Value, "foo") unwrapped := unwrapError(wrapped) test.AssertEquals(t, wrapped.Type, reflect.TypeOf(unwrapped).Name()) test.AssertEquals(t, unwrapped.Error(), "foo") } complicated := []struct { given error expected error }{ { &probs.ProblemDetails{ Type: probs.ConnectionProblem, Detail: "whoops", HTTPStatus: 417, }, &probs.ProblemDetails{ Type: probs.ConnectionProblem, Detail: "whoops", HTTPStatus: 417, }, }, { &probs.ProblemDetails{Type: "invalid", Detail: "hm"}, errors.New("hm"), }, { errors.New(""), errors.New(""), }, } for i, tc := range complicated { actual := unwrapError(wrapError(tc.given)) if !reflect.DeepEqual(tc.expected, actual) { t.Errorf("rpc error wrapping case %d: want %#v, got %#v", i, tc.expected, actual) } } }
// GetRegistration obtains a Registration by ID func (ssa *SQLStorageAuthority) GetRegistration(id int64) (core.Registration, error) { regObj, err := ssa.dbMap.Get(regModel{}, id) if err != nil { return core.Registration{}, err } if regObj == nil { msg := fmt.Sprintf("No registrations with ID %d", id) return core.Registration{}, core.NoSuchRegistrationError(msg) } regPtr, ok := regObj.(*regModel) if !ok { return core.Registration{}, fmt.Errorf("Invalid cast to reg model object") } return modelToRegistration(regPtr) }
// GetRegistrationByKey obtains a Registration by JWK func (ssa *SQLStorageAuthority) GetRegistrationByKey(key jose.JsonWebKey) (core.Registration, error) { reg := ®Model{} sha, err := core.KeyDigest(key.Key) if err != nil { return core.Registration{}, err } err = ssa.dbMap.SelectOne(reg, "SELECT * FROM registrations WHERE jwk_sha256 = :key", map[string]interface{}{"key": sha}) if err == sql.ErrNoRows { msg := fmt.Sprintf("No registrations with public key sha256 %s", sha) return core.Registration{}, core.NoSuchRegistrationError(msg) } if err != nil { return core.Registration{}, err } return modelToRegistration(reg) }
// GetRegistration obtains a Registration by ID func (ssa *SQLStorageAuthority) GetRegistration(ctx context.Context, id int64) (core.Registration, error) { const query = "WHERE id = ?" var model interface{} var err error if features.Enabled(features.AllowAccountDeactivation) { model, err = selectRegistrationv2(ssa.dbMap, query, id) } else { model, err = selectRegistration(ssa.dbMap, query, id) } if err == sql.ErrNoRows { return core.Registration{}, core.NoSuchRegistrationError( fmt.Sprintf("No registrations with ID %d", id), ) } if err != nil { return core.Registration{}, err } return modelToRegistration(model) }
func TestWrapError(t *testing.T) { testCases := []error{ core.InternalServerError("foo"), core.NotSupportedError("foo"), core.MalformedRequestError("foo"), core.UnauthorizedError("foo"), core.NotFoundError("foo"), core.SyntaxError("foo"), core.SignatureValidationError("foo"), core.CertificateIssuanceError("foo"), core.NoSuchRegistrationError("foo"), core.RateLimitedError("foo"), core.TooManyRPCRequestsError("foo"), } for _, c := range testCases { wrapped := wrapError(c) test.AssertEquals(t, wrapped.Type, reflect.TypeOf(c).Name()) test.AssertEquals(t, wrapped.Value, "foo") unwrapped := unwrapError(wrapped) test.AssertEquals(t, wrapped.Type, reflect.TypeOf(unwrapped).Name()) test.AssertEquals(t, unwrapped.Error(), "foo") } }
func TestErrors(t *testing.T) { testcases := []struct { err error expectedCode codes.Code }{ {core.MalformedRequestError("test 1"), MalformedRequestError}, {core.NotSupportedError("test 2"), NotSupportedError}, {core.UnauthorizedError("test 3"), UnauthorizedError}, {core.NotFoundError("test 4"), NotFoundError}, {core.LengthRequiredError("test 5"), LengthRequiredError}, {core.SignatureValidationError("test 6"), SignatureValidationError}, {core.RateLimitedError("test 7"), RateLimitedError}, {core.BadNonceError("test 8"), BadNonceError}, {core.NoSuchRegistrationError("test 9"), NoSuchRegistrationError}, {core.InternalServerError("test 10"), InternalServerError}, } for _, tc := range testcases { wrappedErr := wrapError(tc.err) test.AssertEquals(t, grpc.Code(wrappedErr), tc.expectedCode) test.AssertEquals(t, tc.err, unwrapError(wrappedErr)) } }