...

Source file src/github.com/letsencrypt/boulder/sa/type-converter.go

Documentation: github.com/letsencrypt/boulder/sa

     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  // BoulderTypeConverter is used by borp for storing objects in DB.
    16  type BoulderTypeConverter struct{}
    17  
    18  // ToDb converts a Boulder object to one suitable for the DB representation.
    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  // FromDb converts a DB representation back into a Boulder object.
    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