...
1 package openid
2
3 import (
4 "bytes"
5 "fmt"
6 "io"
7 "regexp"
8 "strconv"
9
10 "github.com/lestrrat-go/jwx/internal/json"
11
12 "github.com/pkg/errors"
13 )
14
15
16
17
18
19
20
21
22
23 type BirthdateClaim struct {
24 year *int
25 month *int
26 day *int
27 }
28
29 func (b BirthdateClaim) Year() int {
30 if b.year == nil {
31 return 0
32 }
33 return *(b.year)
34 }
35
36 func (b BirthdateClaim) Month() int {
37 if b.month == nil {
38 return 0
39 }
40 return *(b.month)
41 }
42
43 func (b BirthdateClaim) Day() int {
44 if b.day == nil {
45 return 0
46 }
47 return *(b.day)
48 }
49
50 func (b *BirthdateClaim) UnmarshalJSON(data []byte) error {
51 var s string
52 if err := json.Unmarshal(data, &s); err != nil {
53 return errors.Wrap(err, `failed to unmarshal JSON string for birthdate claim`)
54 }
55
56 if err := b.Accept(s); err != nil {
57 return errors.Wrap(err, `failed to accept JSON value for birthdate claim`)
58 }
59 return nil
60 }
61
62 func tointptr(v int64) *int {
63 i := int(v)
64 return &i
65 }
66
67 var birthdateRx = regexp.MustCompile(`^(\d{4})-(\d{2})-(\d{2})$`)
68
69
70
71
72 func (b *BirthdateClaim) Accept(v interface{}) error {
73 b.year = nil
74 b.month = nil
75 b.day = nil
76 switch v := v.(type) {
77 case *BirthdateClaim:
78 if ptr := v.year; ptr != nil {
79 year := *ptr
80 b.year = &year
81 }
82 if ptr := v.month; ptr != nil {
83 month := *ptr
84 b.month = &month
85 }
86 if ptr := v.day; ptr != nil {
87 day := *ptr
88 b.day = &day
89 }
90 return nil
91 case string:
92
93 indices := birthdateRx.FindStringSubmatchIndex(v)
94 if indices == nil {
95 return errors.New(`invalid pattern for birthdate`)
96 }
97 var tmp BirthdateClaim
98
99
100
101
102
103
104
105 year, _ := strconv.ParseInt(v[indices[2]:indices[3]], 10, 64)
106 if year <= 0 {
107 return errors.New(`failed to parse birthdate year`)
108 }
109 tmp.year = tointptr(year)
110
111 month, _ := strconv.ParseInt(v[indices[4]:indices[5]], 10, 64)
112 if month <= 0 {
113 return errors.New(`failed to parse birthdate month`)
114 }
115 tmp.month = tointptr(month)
116
117 day, _ := strconv.ParseInt(v[indices[6]:indices[7]], 10, 64)
118 if day <= 0 {
119 return errors.New(`failed to parse birthdate day`)
120 }
121 tmp.day = tointptr(day)
122
123 *b = tmp
124 return nil
125 default:
126 return errors.Errorf(`invalid type for birthdate: %T`, v)
127 }
128 }
129
130 func (b BirthdateClaim) encode(dst io.Writer) {
131 fmt.Fprintf(dst, "%04d-%02d-%02d", b.Year(), b.Month(), b.Day())
132 }
133
134 func (b BirthdateClaim) String() string {
135 var buf bytes.Buffer
136 b.encode(&buf)
137 return buf.String()
138 }
139
140 func (b BirthdateClaim) MarshalText() ([]byte, error) {
141 var buf bytes.Buffer
142 b.encode(&buf)
143 return buf.Bytes(), nil
144 }
145
View as plain text