1 package sa
2
3 import (
4 "context"
5 "strings"
6 "time"
7
8 "github.com/letsencrypt/boulder/db"
9 sapb "github.com/letsencrypt/boulder/sa/proto"
10 "github.com/weppos/publicsuffix-go/publicsuffix"
11 )
12
13
14
15 func baseDomain(name string) string {
16 eTLDPlusOne, err := publicsuffix.Domain(name)
17 if err != nil {
18
19
20
21
22
23
24
25
26 return name
27 }
28 return eTLDPlusOne
29 }
30
31
32
33
34 func (ssa *SQLStorageAuthority) addCertificatesPerName(ctx context.Context, db db.SelectExecer, names []string, timeToTheHour time.Time) error {
35
36 baseDomainsMap := make(map[string]bool)
37 var qmarks []string
38 var values []interface{}
39 for _, name := range names {
40 base := baseDomain(name)
41 if !baseDomainsMap[base] {
42 baseDomainsMap[base] = true
43 values = append(values, base, timeToTheHour, 1)
44 qmarks = append(qmarks, "(?, ?, ?)")
45 }
46 }
47
48 _, err := db.ExecContext(ctx, `INSERT INTO certificatesPerName (eTLDPlusOne, time, count) VALUES `+
49 strings.Join(qmarks, ", ")+` ON DUPLICATE KEY UPDATE count=count+1;`,
50 values...)
51 if err != nil {
52 return err
53 }
54
55 return nil
56 }
57
58
59
60 func (ssa *SQLStorageAuthorityRO) countCertificates(ctx context.Context, dbMap db.Selector, domain string, timeRange *sapb.Range) (int64, time.Time, error) {
61 latest := time.Unix(0, timeRange.LatestNS)
62 var results []struct {
63 Count int64
64 Time time.Time
65 }
66 _, err := dbMap.Select(
67 ctx,
68 &results,
69 `SELECT count, time FROM certificatesPerName
70 WHERE eTLDPlusOne = :baseDomain AND
71 time > :earliest AND
72 time <= :latest`,
73 map[string]interface{}{
74 "baseDomain": baseDomain(domain),
75 "earliest": time.Unix(0, timeRange.EarliestNS),
76 "latest": latest,
77 })
78 if err != nil {
79 if db.IsNoRows(err) {
80 return 0, time.Time{}, nil
81 }
82 return 0, time.Time{}, err
83 }
84
85
86 var earliest = latest
87 var total int64
88 for _, r := range results {
89 total += r.Count
90 if r.Time.Before(earliest) {
91 earliest = r.Time
92 }
93 }
94 if total <= 0 && earliest == latest {
95
96 return total, time.Time{}, nil
97 }
98 return total, earliest, nil
99 }
100
101
102
103
104 func addNewOrdersRateLimit(ctx context.Context, dbMap db.SelectExecer, regID int64, timeToTheMinute time.Time) error {
105 _, err := dbMap.ExecContext(ctx, `INSERT INTO newOrdersRL
106 (regID, time, count)
107 VALUES (?, ?, 1)
108 ON DUPLICATE KEY UPDATE count=count+1;`,
109 regID,
110 timeToTheMinute,
111 )
112 if err != nil {
113 return err
114 }
115 return nil
116 }
117
118
119
120 func countNewOrders(ctx context.Context, dbMap db.Selector, req *sapb.CountOrdersRequest) (*sapb.Count, error) {
121 var counts []int64
122 _, err := dbMap.Select(
123 ctx,
124 &counts,
125 `SELECT count FROM newOrdersRL
126 WHERE regID = :regID AND
127 time > :earliest AND
128 time <= :latest`,
129 map[string]interface{}{
130 "regID": req.AccountID,
131 "earliest": time.Unix(0, req.Range.EarliestNS),
132 "latest": time.Unix(0, req.Range.LatestNS),
133 },
134 )
135 if err != nil {
136 if db.IsNoRows(err) {
137 return &sapb.Count{Count: 0}, nil
138 }
139 return nil, err
140 }
141 var total int64
142 for _, count := range counts {
143 total += count
144 }
145 return &sapb.Count{Count: total}, nil
146 }
147
View as plain text