Go · 8925 bytes Raw Blame History
1 // Code generated by sqlc. DO NOT EDIT.
2 // versions:
3 // sqlc v1.31.1
4 // source: user_gpg_keys.sql
5
6 package usersdb
7
8 import (
9 "context"
10
11 "github.com/jackc/pgx/v5/pgtype"
12 )
13
14 const countUserGPGKeys = `-- name: CountUserGPGKeys :one
15 SELECT count(*) FROM user_gpg_keys WHERE user_id = $1 AND revoked_at IS NULL
16 `
17
18 // Excludes revoked rows so the per-user cap (100) counts live keys.
19 func (q *Queries) CountUserGPGKeys(ctx context.Context, db DBTX, userID int64) (int64, error) {
20 row := db.QueryRow(ctx, countUserGPGKeys, userID)
21 var count int64
22 err := row.Scan(&count)
23 return count, err
24 }
25
26 const getUserGPGKey = `-- name: GetUserGPGKey :one
27 SELECT id, user_id, name, fingerprint, key_id, armored,
28 can_sign, can_encrypt_comms, can_encrypt_storage, can_certify, can_authenticate,
29 uids, subkeys, primary_algo,
30 created_at, last_used_at, revoked_at, expires_at
31 FROM user_gpg_keys
32 WHERE id = $1 AND user_id = $2 AND revoked_at IS NULL
33 `
34
35 type GetUserGPGKeyParams struct {
36 ID int64
37 UserID int64
38 }
39
40 // Scoped single-key lookup for REST GET-by-id. user_id filter prevents
41 // cross-user reads (existence-leak-safe: returns no row if the id
42 // belongs to another user). Excludes soft-deleted rows so the public
43 // surface mirrors a hard delete from the consumer's perspective;
44 // verification (which needs historical attribution) uses
45 // GetUserGPGKeyForVerification which has no revoked filter.
46 func (q *Queries) GetUserGPGKey(ctx context.Context, db DBTX, arg GetUserGPGKeyParams) (UserGpgKey, error) {
47 row := db.QueryRow(ctx, getUserGPGKey, arg.ID, arg.UserID)
48 var i UserGpgKey
49 err := row.Scan(
50 &i.ID,
51 &i.UserID,
52 &i.Name,
53 &i.Fingerprint,
54 &i.KeyID,
55 &i.Armored,
56 &i.CanSign,
57 &i.CanEncryptComms,
58 &i.CanEncryptStorage,
59 &i.CanCertify,
60 &i.CanAuthenticate,
61 &i.Uids,
62 &i.Subkeys,
63 &i.PrimaryAlgo,
64 &i.CreatedAt,
65 &i.LastUsedAt,
66 &i.RevokedAt,
67 &i.ExpiresAt,
68 )
69 return i, err
70 }
71
72 const getUserGPGKeyByFingerprint = `-- name: GetUserGPGKeyByFingerprint :one
73 SELECT id, user_id, name, fingerprint, key_id, armored,
74 can_sign, can_encrypt_comms, can_encrypt_storage, can_certify, can_authenticate,
75 uids, subkeys, primary_algo,
76 created_at, last_used_at, revoked_at, expires_at
77 FROM user_gpg_keys
78 WHERE fingerprint = $1 AND revoked_at IS NULL
79 `
80
81 // Uniqueness probe used by the add path to surface a friendly
82 // "this key is already registered" error before the unique index
83 // violation. Returns any row matching the fingerprint regardless of
84 // which user owns it (global uniqueness is the contract).
85 func (q *Queries) GetUserGPGKeyByFingerprint(ctx context.Context, db DBTX, fingerprint string) (UserGpgKey, error) {
86 row := db.QueryRow(ctx, getUserGPGKeyByFingerprint, fingerprint)
87 var i UserGpgKey
88 err := row.Scan(
89 &i.ID,
90 &i.UserID,
91 &i.Name,
92 &i.Fingerprint,
93 &i.KeyID,
94 &i.Armored,
95 &i.CanSign,
96 &i.CanEncryptComms,
97 &i.CanEncryptStorage,
98 &i.CanCertify,
99 &i.CanAuthenticate,
100 &i.Uids,
101 &i.Subkeys,
102 &i.PrimaryAlgo,
103 &i.CreatedAt,
104 &i.LastUsedAt,
105 &i.RevokedAt,
106 &i.ExpiresAt,
107 )
108 return i, err
109 }
110
111 const getUserGPGKeyForVerification = `-- name: GetUserGPGKeyForVerification :one
112 SELECT id, user_id, name, fingerprint, key_id, armored,
113 can_sign, can_encrypt_comms, can_encrypt_storage, can_certify, can_authenticate,
114 uids, subkeys, primary_algo,
115 created_at, last_used_at, revoked_at, expires_at
116 FROM user_gpg_keys
117 WHERE id = $1
118 `
119
120 // Non-user-scoped lookup used by the verification path. Unlike
121 // GetUserGPGKey this query does NOT filter on user_id — the caller
122 // already validated the subkey resolution and needs the parent
123 // record's user_id to drive the email cross-check. Includes revoked
124 // rows so historical commit verifications can still resolve their
125 // signer attribution.
126 func (q *Queries) GetUserGPGKeyForVerification(ctx context.Context, db DBTX, id int64) (UserGpgKey, error) {
127 row := db.QueryRow(ctx, getUserGPGKeyForVerification, id)
128 var i UserGpgKey
129 err := row.Scan(
130 &i.ID,
131 &i.UserID,
132 &i.Name,
133 &i.Fingerprint,
134 &i.KeyID,
135 &i.Armored,
136 &i.CanSign,
137 &i.CanEncryptComms,
138 &i.CanEncryptStorage,
139 &i.CanCertify,
140 &i.CanAuthenticate,
141 &i.Uids,
142 &i.Subkeys,
143 &i.PrimaryAlgo,
144 &i.CreatedAt,
145 &i.LastUsedAt,
146 &i.RevokedAt,
147 &i.ExpiresAt,
148 )
149 return i, err
150 }
151
152 const insertUserGPGKey = `-- name: InsertUserGPGKey :one
153
154 INSERT INTO user_gpg_keys (
155 user_id, name, fingerprint, key_id, armored,
156 can_sign, can_encrypt_comms, can_encrypt_storage, can_certify, can_authenticate,
157 uids, subkeys, primary_algo, expires_at
158 )
159 VALUES (
160 $1, $2, $3, $4, $5,
161 $6, $7, $8, $9, $10,
162 $11, $12, $13, $14
163 )
164 RETURNING id, user_id, name, fingerprint, key_id, armored,
165 can_sign, can_encrypt_comms, can_encrypt_storage, can_certify, can_authenticate,
166 uids, subkeys, primary_algo,
167 created_at, last_used_at, revoked_at, expires_at
168 `
169
170 type InsertUserGPGKeyParams struct {
171 UserID int64
172 Name string
173 Fingerprint string
174 KeyID string
175 Armored string
176 CanSign bool
177 CanEncryptComms bool
178 CanEncryptStorage bool
179 CanCertify bool
180 CanAuthenticate bool
181 Uids []string
182 Subkeys []byte
183 PrimaryAlgo string
184 ExpiresAt pgtype.Timestamptz
185 }
186
187 // SPDX-License-Identifier: AGPL-3.0-or-later
188 // Inserts a parsed primary GPG key. Subkeys land in user_gpg_subkeys
189 // in the same transaction (see InsertUserGPGSubkey). expires_at is
190 // nullable; many keys have no expiration. revoked_at stays NULL on
191 // insert; soft-delete sets it.
192 func (q *Queries) InsertUserGPGKey(ctx context.Context, db DBTX, arg InsertUserGPGKeyParams) (UserGpgKey, error) {
193 row := db.QueryRow(ctx, insertUserGPGKey,
194 arg.UserID,
195 arg.Name,
196 arg.Fingerprint,
197 arg.KeyID,
198 arg.Armored,
199 arg.CanSign,
200 arg.CanEncryptComms,
201 arg.CanEncryptStorage,
202 arg.CanCertify,
203 arg.CanAuthenticate,
204 arg.Uids,
205 arg.Subkeys,
206 arg.PrimaryAlgo,
207 arg.ExpiresAt,
208 )
209 var i UserGpgKey
210 err := row.Scan(
211 &i.ID,
212 &i.UserID,
213 &i.Name,
214 &i.Fingerprint,
215 &i.KeyID,
216 &i.Armored,
217 &i.CanSign,
218 &i.CanEncryptComms,
219 &i.CanEncryptStorage,
220 &i.CanCertify,
221 &i.CanAuthenticate,
222 &i.Uids,
223 &i.Subkeys,
224 &i.PrimaryAlgo,
225 &i.CreatedAt,
226 &i.LastUsedAt,
227 &i.RevokedAt,
228 &i.ExpiresAt,
229 )
230 return i, err
231 }
232
233 const listUserGPGKeys = `-- name: ListUserGPGKeys :many
234 SELECT id, user_id, name, fingerprint, key_id, armored,
235 can_sign, can_encrypt_comms, can_encrypt_storage, can_certify, can_authenticate,
236 uids, subkeys, primary_algo,
237 created_at, last_used_at, revoked_at, expires_at
238 FROM user_gpg_keys
239 WHERE user_id = $1 AND revoked_at IS NULL
240 ORDER BY created_at DESC
241 LIMIT $2 OFFSET $3
242 `
243
244 type ListUserGPGKeysParams struct {
245 UserID int64
246 Limit int32
247 Offset int32
248 }
249
250 // Paginated list for the REST surface; HTML settings page reuses with
251 // a generous limit and no offset.
252 func (q *Queries) ListUserGPGKeys(ctx context.Context, db DBTX, arg ListUserGPGKeysParams) ([]UserGpgKey, error) {
253 rows, err := db.Query(ctx, listUserGPGKeys, arg.UserID, arg.Limit, arg.Offset)
254 if err != nil {
255 return nil, err
256 }
257 defer rows.Close()
258 items := []UserGpgKey{}
259 for rows.Next() {
260 var i UserGpgKey
261 if err := rows.Scan(
262 &i.ID,
263 &i.UserID,
264 &i.Name,
265 &i.Fingerprint,
266 &i.KeyID,
267 &i.Armored,
268 &i.CanSign,
269 &i.CanEncryptComms,
270 &i.CanEncryptStorage,
271 &i.CanCertify,
272 &i.CanAuthenticate,
273 &i.Uids,
274 &i.Subkeys,
275 &i.PrimaryAlgo,
276 &i.CreatedAt,
277 &i.LastUsedAt,
278 &i.RevokedAt,
279 &i.ExpiresAt,
280 ); err != nil {
281 return nil, err
282 }
283 items = append(items, i)
284 }
285 if err := rows.Err(); err != nil {
286 return nil, err
287 }
288 return items, nil
289 }
290
291 const softDeleteUserGPGKey = `-- name: SoftDeleteUserGPGKey :execrows
292 UPDATE user_gpg_keys
293 SET revoked_at = now()
294 WHERE id = $1 AND user_id = $2 AND revoked_at IS NULL
295 `
296
297 type SoftDeleteUserGPGKeyParams struct {
298 ID int64
299 UserID int64
300 }
301
302 // Scoped soft-delete: stamps revoked_at, preserves the row for audit
303 // continuity. Returns the number of rows affected so the handler can
304 // distinguish "not found" from "deleted" without a follow-up query.
305 func (q *Queries) SoftDeleteUserGPGKey(ctx context.Context, db DBTX, arg SoftDeleteUserGPGKeyParams) (int64, error) {
306 result, err := db.Exec(ctx, softDeleteUserGPGKey, arg.ID, arg.UserID)
307 if err != nil {
308 return 0, err
309 }
310 return result.RowsAffected(), nil
311 }
312
313 const touchUserGPGKeyLastUsed = `-- name: TouchUserGPGKeyLastUsed :exec
314 UPDATE user_gpg_keys SET last_used_at = now() WHERE id = $1
315 `
316
317 // Best-effort last-used stamp called from the verification path when
318 // a signature successfully resolves to this key. No timeout / error
319 // propagation; the caller fires-and-forgets via a goroutine.
320 func (q *Queries) TouchUserGPGKeyLastUsed(ctx context.Context, db DBTX, id int64) error {
321 _, err := db.Exec(ctx, touchUserGPGKeyLastUsed, id)
322 return err
323 }
324