1 package sa
2
3 import (
4 "encoding/json"
5 "errors"
6 "fmt"
7
8 "github.com/letsencrypt/borp"
9 "gopkg.in/go-jose/go-jose.v2"
10
11 "github.com/letsencrypt/boulder/core"
12 "github.com/letsencrypt/boulder/identifier"
13 )
14
15
16 type BoulderTypeConverter struct{}
17
18
19 func (tc BoulderTypeConverter) ToDb(val interface{}) (interface{}, error) {
20 switch t := val.(type) {
21 case identifier.ACMEIdentifier, []core.Challenge, []string, [][]int:
22 jsonBytes, err := json.Marshal(t)
23 if err != nil {
24 return nil, err
25 }
26 return string(jsonBytes), nil
27 case jose.JSONWebKey:
28 jsonBytes, err := t.MarshalJSON()
29 if err != nil {
30 return "", err
31 }
32 return string(jsonBytes), nil
33 case core.AcmeStatus:
34 return string(t), nil
35 case core.OCSPStatus:
36 return string(t), nil
37 default:
38 return val, nil
39 }
40 }
41
42
43 func (tc BoulderTypeConverter) FromDb(target interface{}) (borp.CustomScanner, bool) {
44 switch target.(type) {
45 case *identifier.ACMEIdentifier, *[]core.Challenge, *[]string, *[][]int:
46 binder := func(holder, target interface{}) error {
47 s, ok := holder.(*string)
48 if !ok {
49 return errors.New("FromDb: Unable to convert *string")
50 }
51 b := []byte(*s)
52 err := json.Unmarshal(b, target)
53 if err != nil {
54 return badJSONError(
55 fmt.Sprintf("binder failed to unmarshal %T", target),
56 b,
57 err)
58 }
59 return nil
60 }
61 return borp.CustomScanner{Holder: new(string), Target: target, Binder: binder}, true
62 case *jose.JSONWebKey:
63 binder := func(holder, target interface{}) error {
64 s, ok := holder.(*string)
65 if !ok {
66 return fmt.Errorf("FromDb: Unable to convert %T to *string", holder)
67 }
68 if *s == "" {
69 return errors.New("FromDb: Empty JWK field.")
70 }
71 b := []byte(*s)
72 k, ok := target.(*jose.JSONWebKey)
73 if !ok {
74 return fmt.Errorf("FromDb: Unable to convert %T to *jose.JSONWebKey", target)
75 }
76 err := k.UnmarshalJSON(b)
77 if err != nil {
78 return badJSONError(
79 "binder failed to unmarshal JWK",
80 b,
81 err)
82 }
83 return nil
84 }
85 return borp.CustomScanner{Holder: new(string), Target: target, Binder: binder}, true
86 case *core.AcmeStatus:
87 binder := func(holder, target interface{}) error {
88 s, ok := holder.(*string)
89 if !ok {
90 return fmt.Errorf("FromDb: Unable to convert %T to *string", holder)
91 }
92 st, ok := target.(*core.AcmeStatus)
93 if !ok {
94 return fmt.Errorf("FromDb: Unable to convert %T to *core.AcmeStatus", target)
95 }
96
97 *st = core.AcmeStatus(*s)
98 return nil
99 }
100 return borp.CustomScanner{Holder: new(string), Target: target, Binder: binder}, true
101 case *core.OCSPStatus:
102 binder := func(holder, target interface{}) error {
103 s, ok := holder.(*string)
104 if !ok {
105 return fmt.Errorf("FromDb: Unable to convert %T to *string", holder)
106 }
107 st, ok := target.(*core.OCSPStatus)
108 if !ok {
109 return fmt.Errorf("FromDb: Unable to convert %T to *core.OCSPStatus", target)
110 }
111
112 *st = core.OCSPStatus(*s)
113 return nil
114 }
115 return borp.CustomScanner{Holder: new(string), Target: target, Binder: binder}, true
116 default:
117 return borp.CustomScanner{}, false
118 }
119 }
120
View as plain text