mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-11-10 14:44:04 +08:00
Add Manager.UsersByIDs, a bulk user lookup for the rate visitor refresh
This commit is contained in:
1 parent
6ae42e7590
commit
14f631da8f
4 files changed
+39
No files matched your search
@@ -26,6 +26,7 @@ const (
|
||||
syncTopicPrefix = "st_"
|
||||
syncTopicLength = 16
|
||||
userIDPrefix = "u_"
|
||||
usersByIDsChunk = 1000 // IDs per statement of UsersByIDs
|
||||
userIDLength = 12
|
||||
userAuthIntentionalSlowDownHash = "$2a$10$YFCQvqQDwIIwnJM1xkAYOeih0dg17UVGanaTStnrSzC8NCWxcLDwy" // Cost should match DefaultUserPasswordBcryptCost
|
||||
userHardDeleteAfterDuration = 7 * 24 * time.Hour
|
||||
@@ -457,6 +458,29 @@ func (a *Manager) UserByID(id string) (*User, error) {
|
||||
return a.readUser(rows)
|
||||
}
|
||||
|
||||
// UsersByIDs returns the users with the given IDs, in chunks of usersByIDsChunk, skipping the IDs
|
||||
// that do not exist. Deleted users are returned as such; the caller decides what to do with them.
|
||||
// The IDs are passed as one JSON array, which both dialects unpack, so the statement is fixed.
|
||||
func (a *Manager) UsersByIDs(ids []string) ([]*User, error) {
|
||||
users := make([]*User, 0, len(ids))
|
||||
for chunk := range slices.Chunk(ids, usersByIDsChunk) {
|
||||
param, err := json.Marshal(chunk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows, err := a.db.Query(a.queries.selectUsersByIDs, string(param))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chunkUsers, err := a.readUsers(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
users = append(users, chunkUsers...)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// UserByEmailOrUsername resolves an identifier to a single user, trying it first as a primary
|
||||
// email address and then as a username. A verified, owned email takes precedence over a
|
||||
// freely-chosen username, so a look-alike username cannot shadow the email's real owner. Returns
|
||||
|
||||
@@ -25,6 +25,12 @@ const (
|
||||
LEFT JOIN tier t on t.id = u.tier_id
|
||||
WHERE u.id = $1
|
||||
`
|
||||
postgresSelectUsersByIDsQuery = `
|
||||
SELECT u.id, u.user_name, u.pass, u.role, u.prefs, u.sync_topic, u.provisioned, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, u.stripe_subscription_interval, u.stripe_subscription_paid_until, u.stripe_subscription_cancel_at, u.deleted, t.id, t.code, t.name, t.messages_limit, t.messages_expiry_duration, t.emails_limit, t.calls_limit, t.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_monthly_price_id, t.stripe_yearly_price_id
|
||||
FROM "user" u
|
||||
LEFT JOIN tier t on t.id = u.tier_id
|
||||
WHERE u.id IN (SELECT jsonb_array_elements_text($1::jsonb))
|
||||
`
|
||||
postgresSelectUserByNameQuery = `
|
||||
SELECT u.id, u.user_name, u.pass, u.role, u.prefs, u.sync_topic, u.provisioned, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, u.stripe_subscription_interval, u.stripe_subscription_paid_until, u.stripe_subscription_cancel_at, u.deleted, t.id, t.code, t.name, t.messages_limit, t.messages_expiry_duration, t.emails_limit, t.calls_limit, t.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_monthly_price_id, t.stripe_yearly_price_id
|
||||
FROM "user" u
|
||||
@@ -257,6 +263,7 @@ const (
|
||||
// NewPostgresManager creates a new Manager backed by a PostgreSQL database using an existing connection pool.
|
||||
var postgresQueries = queries{
|
||||
selectUserByID: postgresSelectUserByIDQuery,
|
||||
selectUsersByIDs: postgresSelectUsersByIDsQuery,
|
||||
selectUserByName: postgresSelectUserByNameQuery,
|
||||
selectUserByNameOrPrimaryEmail: postgresSelectUserByNameOrPrimaryEmailQuery,
|
||||
selectUserByToken: postgresSelectUserByTokenQuery,
|
||||
|
||||
@@ -31,6 +31,12 @@ const (
|
||||
LEFT JOIN tier t on t.id = u.tier_id
|
||||
WHERE u.id = ?
|
||||
`
|
||||
sqliteSelectUsersByIDsQuery = `
|
||||
SELECT u.id, u.user, u.pass, u.role, u.prefs, u.sync_topic, u.provisioned, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, u.stripe_subscription_interval, u.stripe_subscription_paid_until, u.stripe_subscription_cancel_at, deleted, t.id, t.code, t.name, t.messages_limit, t.messages_expiry_duration, t.emails_limit, t.calls_limit, t.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_monthly_price_id, t.stripe_yearly_price_id
|
||||
FROM user u
|
||||
LEFT JOIN tier t on t.id = u.tier_id
|
||||
WHERE u.id IN (SELECT value FROM json_each(?))
|
||||
`
|
||||
sqliteSelectUserByNameQuery = `
|
||||
SELECT u.id, u.user, u.pass, u.role, u.prefs, u.sync_topic, u.provisioned, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, u.stripe_subscription_interval, u.stripe_subscription_paid_until, u.stripe_subscription_cancel_at, deleted, t.id, t.code, t.name, t.messages_limit, t.messages_expiry_duration, t.emails_limit, t.calls_limit, t.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_monthly_price_id, t.stripe_yearly_price_id
|
||||
FROM user u
|
||||
@@ -255,6 +261,7 @@ const (
|
||||
|
||||
var sqliteQueries = queries{
|
||||
selectUserByID: sqliteSelectUserByIDQuery,
|
||||
selectUsersByIDs: sqliteSelectUsersByIDsQuery,
|
||||
selectUserByName: sqliteSelectUserByNameQuery,
|
||||
selectUserByNameOrPrimaryEmail: sqliteSelectUserByNameOrPrimaryEmailQuery,
|
||||
selectUserByToken: sqliteSelectUserByTokenQuery,
|
||||
|
||||
@@ -356,6 +356,7 @@ var (
|
||||
type queries struct {
|
||||
// User queries
|
||||
selectUserByID string
|
||||
selectUsersByIDs string
|
||||
selectUserByName string
|
||||
selectUserByNameOrPrimaryEmail string
|
||||
selectUserByToken string
|
||||
|
||||
Reference in new issue
Block a user