|
@@ -1,3 +1,4 @@
|
|
|
|
|
+// Package user deals with authentication and authorization against topics
|
|
|
package user
|
|
package user
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
@@ -28,7 +29,7 @@ const (
|
|
|
tokenPrefix = "tk_"
|
|
tokenPrefix = "tk_"
|
|
|
tokenLength = 32
|
|
tokenLength = 32
|
|
|
tokenMaxCount = 20 // Only keep this many tokens in the table per user
|
|
tokenMaxCount = 20 // Only keep this many tokens in the table per user
|
|
|
- tagManager = "user_manager"
|
|
|
|
|
|
|
+ tag = "user_manager"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Default constants that may be overridden by configs
|
|
// Default constants that may be overridden by configs
|
|
@@ -47,7 +48,7 @@ var (
|
|
|
const (
|
|
const (
|
|
|
createTablesQueriesNoTx = `
|
|
createTablesQueriesNoTx = `
|
|
|
CREATE TABLE IF NOT EXISTS tier (
|
|
CREATE TABLE IF NOT EXISTS tier (
|
|
|
- id TEXT PRIMARY KEY,
|
|
|
|
|
|
|
+ id TEXT PRIMARY KEY,
|
|
|
code TEXT NOT NULL,
|
|
code TEXT NOT NULL,
|
|
|
name TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
|
messages_limit INT NOT NULL,
|
|
messages_limit INT NOT NULL,
|
|
@@ -89,7 +90,7 @@ const (
|
|
|
topic TEXT NOT NULL,
|
|
topic TEXT NOT NULL,
|
|
|
read INT NOT NULL,
|
|
read INT NOT NULL,
|
|
|
write INT NOT NULL,
|
|
write INT NOT NULL,
|
|
|
- owner_user_id INT,
|
|
|
|
|
|
|
+ owner_user_id INT,
|
|
|
PRIMARY KEY (user_id, topic),
|
|
PRIMARY KEY (user_id, topic),
|
|
|
FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE,
|
|
FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE,
|
|
|
FOREIGN KEY (owner_user_id) REFERENCES user (id) ON DELETE CASCADE
|
|
FOREIGN KEY (owner_user_id) REFERENCES user (id) ON DELETE CASCADE
|
|
@@ -109,7 +110,7 @@ const (
|
|
|
version INT NOT NULL
|
|
version INT NOT NULL
|
|
|
);
|
|
);
|
|
|
INSERT INTO user (id, user, pass, role, sync_topic, created)
|
|
INSERT INTO user (id, user, pass, role, sync_topic, created)
|
|
|
- VALUES ('` + everyoneID + `', '*', '', 'anonymous', '', UNIXEPOCH())
|
|
|
|
|
|
|
+ VALUES ('` + everyoneID + `', '*', '', 'anonymous', '', UNIXEPOCH())
|
|
|
ON CONFLICT (id) DO NOTHING;
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
`
|
|
`
|
|
|
createTablesQueries = `BEGIN; ` + createTablesQueriesNoTx + ` COMMIT;`
|
|
createTablesQueries = `BEGIN; ` + createTablesQueriesNoTx + ` COMMIT;`
|
|
@@ -121,7 +122,7 @@ const (
|
|
|
SELECT u.id, u.user, u.pass, u.role, u.prefs, u.sync_topic, u.stats_messages, u.stats_emails, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, 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.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_price_id
|
|
SELECT u.id, u.user, u.pass, u.role, u.prefs, u.sync_topic, u.stats_messages, u.stats_emails, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, 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.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_price_id
|
|
|
FROM user u
|
|
FROM user u
|
|
|
LEFT JOIN tier t on t.id = u.tier_id
|
|
LEFT JOIN tier t on t.id = u.tier_id
|
|
|
- WHERE u.id = ?
|
|
|
|
|
|
|
+ WHERE u.id = ?
|
|
|
`
|
|
`
|
|
|
selectUserByNameQuery = `
|
|
selectUserByNameQuery = `
|
|
|
SELECT u.id, u.user, u.pass, u.role, u.prefs, u.sync_topic, u.stats_messages, u.stats_emails, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, 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.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_price_id
|
|
SELECT u.id, u.user, u.pass, u.role, u.prefs, u.sync_topic, u.stats_messages, u.stats_emails, u.stripe_customer_id, u.stripe_subscription_id, u.stripe_subscription_status, 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.reservations_limit, t.attachment_file_size_limit, t.attachment_total_size_limit, t.attachment_expiry_duration, t.attachment_bandwidth_limit, t.stripe_price_id
|
|
@@ -151,12 +152,12 @@ const (
|
|
|
`
|
|
`
|
|
|
|
|
|
|
|
insertUserQuery = `
|
|
insertUserQuery = `
|
|
|
- INSERT INTO user (id, user, pass, role, sync_topic, created)
|
|
|
|
|
|
|
+ INSERT INTO user (id, user, pass, role, sync_topic, created)
|
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
|
`
|
|
`
|
|
|
selectUsernamesQuery = `
|
|
selectUsernamesQuery = `
|
|
|
- SELECT user
|
|
|
|
|
- FROM user
|
|
|
|
|
|
|
+ SELECT user
|
|
|
|
|
+ FROM user
|
|
|
ORDER BY
|
|
ORDER BY
|
|
|
CASE role
|
|
CASE role
|
|
|
WHEN 'admin' THEN 1
|
|
WHEN 'admin' THEN 1
|
|
@@ -166,7 +167,7 @@ const (
|
|
|
`
|
|
`
|
|
|
updateUserPassQuery = `UPDATE user SET pass = ? WHERE user = ?`
|
|
updateUserPassQuery = `UPDATE user SET pass = ? WHERE user = ?`
|
|
|
updateUserRoleQuery = `UPDATE user SET role = ? WHERE user = ?`
|
|
updateUserRoleQuery = `UPDATE user SET role = ? WHERE user = ?`
|
|
|
- updateUserPrefsQuery = `UPDATE user SET prefs = ? WHERE user = ?`
|
|
|
|
|
|
|
+ updateUserPrefsQuery = `UPDATE user SET prefs = ? WHERE id = ?`
|
|
|
updateUserStatsQuery = `UPDATE user SET stats_messages = ?, stats_emails = ? WHERE id = ?`
|
|
updateUserStatsQuery = `UPDATE user SET stats_messages = ?, stats_emails = ? WHERE id = ?`
|
|
|
updateUserStatsResetAllQuery = `UPDATE user SET stats_messages = 0, stats_emails = 0`
|
|
updateUserStatsResetAllQuery = `UPDATE user SET stats_messages = 0, stats_emails = 0`
|
|
|
updateUserDeletedQuery = `UPDATE user SET deleted = ? WHERE id = ?`
|
|
updateUserDeletedQuery = `UPDATE user SET deleted = ? WHERE id = ?`
|
|
@@ -174,15 +175,15 @@ const (
|
|
|
deleteUserQuery = `DELETE FROM user WHERE user = ?`
|
|
deleteUserQuery = `DELETE FROM user WHERE user = ?`
|
|
|
|
|
|
|
|
upsertUserAccessQuery = `
|
|
upsertUserAccessQuery = `
|
|
|
- INSERT INTO user_access (user_id, topic, read, write, owner_user_id)
|
|
|
|
|
|
|
+ INSERT INTO user_access (user_id, topic, read, write, owner_user_id)
|
|
|
VALUES ((SELECT id FROM user WHERE user = ?), ?, ?, ?, (SELECT IIF(?='',NULL,(SELECT id FROM user WHERE user=?))))
|
|
VALUES ((SELECT id FROM user WHERE user = ?), ?, ?, ?, (SELECT IIF(?='',NULL,(SELECT id FROM user WHERE user=?))))
|
|
|
- ON CONFLICT (user_id, topic)
|
|
|
|
|
|
|
+ ON CONFLICT (user_id, topic)
|
|
|
DO UPDATE SET read=excluded.read, write=excluded.write, owner_user_id=excluded.owner_user_id
|
|
DO UPDATE SET read=excluded.read, write=excluded.write, owner_user_id=excluded.owner_user_id
|
|
|
`
|
|
`
|
|
|
selectUserAccessQuery = `
|
|
selectUserAccessQuery = `
|
|
|
SELECT topic, read, write
|
|
SELECT topic, read, write
|
|
|
- FROM user_access
|
|
|
|
|
- WHERE user_id = (SELECT id FROM user WHERE user = ?)
|
|
|
|
|
|
|
+ FROM user_access
|
|
|
|
|
+ WHERE user_id = (SELECT id FROM user WHERE user = ?)
|
|
|
ORDER BY write DESC, read DESC, topic
|
|
ORDER BY write DESC, read DESC, topic
|
|
|
`
|
|
`
|
|
|
selectUserReservationsQuery = `
|
|
selectUserReservationsQuery = `
|
|
@@ -201,9 +202,9 @@ const (
|
|
|
selectUserHasReservationQuery = `
|
|
selectUserHasReservationQuery = `
|
|
|
SELECT COUNT(*)
|
|
SELECT COUNT(*)
|
|
|
FROM user_access
|
|
FROM user_access
|
|
|
- WHERE user_id = owner_user_id
|
|
|
|
|
|
|
+ WHERE user_id = owner_user_id
|
|
|
AND owner_user_id = (SELECT id FROM user WHERE user = ?)
|
|
AND owner_user_id = (SELECT id FROM user WHERE user = ?)
|
|
|
- AND topic = ?
|
|
|
|
|
|
|
+ AND topic = ?
|
|
|
`
|
|
`
|
|
|
selectOtherAccessCountQuery = `
|
|
selectOtherAccessCountQuery = `
|
|
|
SELECT COUNT(*)
|
|
SELECT COUNT(*)
|
|
@@ -213,13 +214,13 @@ const (
|
|
|
`
|
|
`
|
|
|
deleteAllAccessQuery = `DELETE FROM user_access`
|
|
deleteAllAccessQuery = `DELETE FROM user_access`
|
|
|
deleteUserAccessQuery = `
|
|
deleteUserAccessQuery = `
|
|
|
- DELETE FROM user_access
|
|
|
|
|
|
|
+ DELETE FROM user_access
|
|
|
WHERE user_id = (SELECT id FROM user WHERE user = ?)
|
|
WHERE user_id = (SELECT id FROM user WHERE user = ?)
|
|
|
OR owner_user_id = (SELECT id FROM user WHERE user = ?)
|
|
OR owner_user_id = (SELECT id FROM user WHERE user = ?)
|
|
|
`
|
|
`
|
|
|
deleteTopicAccessQuery = `
|
|
deleteTopicAccessQuery = `
|
|
|
- DELETE FROM user_access
|
|
|
|
|
- WHERE (user_id = (SELECT id FROM user WHERE user = ?) OR owner_user_id = (SELECT id FROM user WHERE user = ?))
|
|
|
|
|
|
|
+ DELETE FROM user_access
|
|
|
|
|
+ WHERE (user_id = (SELECT id FROM user WHERE user = ?) OR owner_user_id = (SELECT id FROM user WHERE user = ?))
|
|
|
AND topic = ?
|
|
AND topic = ?
|
|
|
`
|
|
`
|
|
|
|
|
|
|
@@ -239,7 +240,7 @@ const (
|
|
|
SELECT user_id, token
|
|
SELECT user_id, token
|
|
|
FROM user_token
|
|
FROM user_token
|
|
|
WHERE user_id = ?
|
|
WHERE user_id = ?
|
|
|
- ORDER BY expires DESC
|
|
|
|
|
|
|
+ ORDER BY expires DESC
|
|
|
LIMIT ?
|
|
LIMIT ?
|
|
|
)
|
|
)
|
|
|
`
|
|
`
|
|
@@ -249,7 +250,7 @@ const (
|
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
|
`
|
|
`
|
|
|
updateTierQuery = `
|
|
updateTierQuery = `
|
|
|
- UPDATE tier
|
|
|
|
|
|
|
+ UPDATE tier
|
|
|
SET name = ?, messages_limit = ?, messages_expiry_duration = ?, emails_limit = ?, reservations_limit = ?, attachment_file_size_limit = ?, attachment_total_size_limit = ?, attachment_expiry_duration = ?, attachment_bandwidth_limit = ?, stripe_price_id = ?
|
|
SET name = ?, messages_limit = ?, messages_expiry_duration = ?, emails_limit = ?, reservations_limit = ?, attachment_file_size_limit = ?, attachment_total_size_limit = ?, attachment_expiry_duration = ?, attachment_bandwidth_limit = ?, stripe_price_id = ?
|
|
|
WHERE code = ?
|
|
WHERE code = ?
|
|
|
`
|
|
`
|
|
@@ -272,7 +273,7 @@ const (
|
|
|
deleteTierQuery = `DELETE FROM tier WHERE code = ?`
|
|
deleteTierQuery = `DELETE FROM tier WHERE code = ?`
|
|
|
|
|
|
|
|
updateBillingQuery = `
|
|
updateBillingQuery = `
|
|
|
- UPDATE user
|
|
|
|
|
|
|
+ UPDATE user
|
|
|
SET stripe_customer_id = ?, stripe_subscription_id = ?, stripe_subscription_status = ?, stripe_subscription_paid_until = ?, stripe_subscription_cancel_at = ?
|
|
SET stripe_customer_id = ?, stripe_subscription_id = ?, stripe_subscription_status = ?, stripe_subscription_paid_until = ?, stripe_subscription_cancel_at = ?
|
|
|
WHERE user = ?
|
|
WHERE user = ?
|
|
|
`
|
|
`
|
|
@@ -291,7 +292,7 @@ const (
|
|
|
`
|
|
`
|
|
|
migrate1To2SelectAllOldUsernamesNoTx = `SELECT user FROM user_old`
|
|
migrate1To2SelectAllOldUsernamesNoTx = `SELECT user FROM user_old`
|
|
|
migrate1To2InsertUserNoTx = `
|
|
migrate1To2InsertUserNoTx = `
|
|
|
- INSERT INTO user (id, user, pass, role, sync_topic, created)
|
|
|
|
|
|
|
+ INSERT INTO user (id, user, pass, role, sync_topic, created)
|
|
|
SELECT ?, user, pass, role, ?, UNIXEPOCH() FROM user_old WHERE user = ?
|
|
SELECT ?, user, pass, role, ?, UNIXEPOCH() FROM user_old WHERE user = ?
|
|
|
`
|
|
`
|
|
|
migrate1To2InsertFromOldTablesAndDropNoTx = `
|
|
migrate1To2InsertFromOldTablesAndDropNoTx = `
|
|
@@ -305,6 +306,12 @@ const (
|
|
|
`
|
|
`
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+var (
|
|
|
|
|
+ migrations = map[int]func(db *sql.DB) error{
|
|
|
|
|
+ 1: migrateFrom1,
|
|
|
|
|
+ }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
// Manager is an implementation of Manager. It stores users and access control list
|
|
// Manager is an implementation of Manager. It stores users and access control list
|
|
|
// in a SQLite database.
|
|
// in a SQLite database.
|
|
|
type Manager struct {
|
|
type Manager struct {
|
|
@@ -350,15 +357,15 @@ func (a *Manager) Authenticate(username, password string) (*User, error) {
|
|
|
}
|
|
}
|
|
|
user, err := a.User(username)
|
|
user, err := a.User(username)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Tag(tagManager).Field("user_name", username).Err(err).Trace("Authentication of user failed (1)")
|
|
|
|
|
|
|
+ log.Tag(tag).Field("user_name", username).Err(err).Trace("Authentication of user failed (1)")
|
|
|
bcrypt.CompareHashAndPassword([]byte(userAuthIntentionalSlowDownHash), []byte("intentional slow-down to avoid timing attacks"))
|
|
bcrypt.CompareHashAndPassword([]byte(userAuthIntentionalSlowDownHash), []byte("intentional slow-down to avoid timing attacks"))
|
|
|
return nil, ErrUnauthenticated
|
|
return nil, ErrUnauthenticated
|
|
|
} else if user.Deleted {
|
|
} else if user.Deleted {
|
|
|
- log.Tag(tagManager).Field("user_name", username).Trace("Authentication of user failed (2): user marked deleted")
|
|
|
|
|
|
|
+ log.Tag(tag).Field("user_name", username).Trace("Authentication of user failed (2): user marked deleted")
|
|
|
bcrypt.CompareHashAndPassword([]byte(userAuthIntentionalSlowDownHash), []byte("intentional slow-down to avoid timing attacks"))
|
|
bcrypt.CompareHashAndPassword([]byte(userAuthIntentionalSlowDownHash), []byte("intentional slow-down to avoid timing attacks"))
|
|
|
return nil, ErrUnauthenticated
|
|
return nil, ErrUnauthenticated
|
|
|
} else if err := bcrypt.CompareHashAndPassword([]byte(user.Hash), []byte(password)); err != nil {
|
|
} else if err := bcrypt.CompareHashAndPassword([]byte(user.Hash), []byte(password)); err != nil {
|
|
|
- log.Tag(tagManager).Field("user_name", username).Err(err).Trace("Authentication of user failed (3)")
|
|
|
|
|
|
|
+ log.Tag(tag).Field("user_name", username).Err(err).Trace("Authentication of user failed (3)")
|
|
|
return nil, ErrUnauthenticated
|
|
return nil, ErrUnauthenticated
|
|
|
}
|
|
}
|
|
|
return user, nil
|
|
return user, nil
|
|
@@ -372,7 +379,7 @@ func (a *Manager) AuthenticateToken(token string) (*User, error) {
|
|
|
}
|
|
}
|
|
|
user, err := a.userByToken(token)
|
|
user, err := a.userByToken(token)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Tag(tagManager).Field("token", token).Err(err).Trace("Authentication of token failed")
|
|
|
|
|
|
|
+ log.Tag(tag).Field("token", token).Err(err).Trace("Authentication of token failed")
|
|
|
return nil, ErrUnauthenticated
|
|
return nil, ErrUnauthenticated
|
|
|
}
|
|
}
|
|
|
user.Token = token
|
|
user.Token = token
|
|
@@ -532,12 +539,12 @@ func (a *Manager) RemoveDeletedUsers() error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ChangeSettings persists the user settings
|
|
// ChangeSettings persists the user settings
|
|
|
-func (a *Manager) ChangeSettings(user *User) error {
|
|
|
|
|
- prefs, err := json.Marshal(user.Prefs)
|
|
|
|
|
|
|
+func (a *Manager) ChangeSettings(userID string, prefs *Prefs) error {
|
|
|
|
|
+ b, err := json.Marshal(prefs)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- if _, err := a.db.Exec(updateUserPrefsQuery, string(prefs), user.Name); err != nil {
|
|
|
|
|
|
|
+ if _, err := a.db.Exec(updateUserPrefsQuery, string(b), userID); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
return nil
|
|
return nil
|
|
@@ -554,9 +561,9 @@ func (a *Manager) ResetStats() error {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// EnqueueStats adds the user to a queue which writes out user stats (messages, emails, ..) in
|
|
|
|
|
|
|
+// EnqueueUserStats adds the user to a queue which writes out user stats (messages, emails, ..) in
|
|
|
// batches at a regular interval
|
|
// batches at a regular interval
|
|
|
-func (a *Manager) EnqueueStats(userID string, stats *Stats) {
|
|
|
|
|
|
|
+func (a *Manager) EnqueueUserStats(userID string, stats *Stats) {
|
|
|
a.mu.Lock()
|
|
a.mu.Lock()
|
|
|
defer a.mu.Unlock()
|
|
defer a.mu.Unlock()
|
|
|
a.statsQueue[userID] = stats
|
|
a.statsQueue[userID] = stats
|
|
@@ -574,10 +581,10 @@ func (a *Manager) asyncQueueWriter(interval time.Duration) {
|
|
|
ticker := time.NewTicker(interval)
|
|
ticker := time.NewTicker(interval)
|
|
|
for range ticker.C {
|
|
for range ticker.C {
|
|
|
if err := a.writeUserStatsQueue(); err != nil {
|
|
if err := a.writeUserStatsQueue(); err != nil {
|
|
|
- log.Tag(tagManager).Err(err).Warn("Writing user stats queue failed")
|
|
|
|
|
|
|
+ log.Tag(tag).Err(err).Warn("Writing user stats queue failed")
|
|
|
}
|
|
}
|
|
|
if err := a.writeTokenUpdateQueue(); err != nil {
|
|
if err := a.writeTokenUpdateQueue(); err != nil {
|
|
|
- log.Tag(tagManager).Err(err).Warn("Writing token update queue failed")
|
|
|
|
|
|
|
+ log.Tag(tag).Err(err).Warn("Writing token update queue failed")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -586,7 +593,7 @@ func (a *Manager) writeUserStatsQueue() error {
|
|
|
a.mu.Lock()
|
|
a.mu.Lock()
|
|
|
if len(a.statsQueue) == 0 {
|
|
if len(a.statsQueue) == 0 {
|
|
|
a.mu.Unlock()
|
|
a.mu.Unlock()
|
|
|
- log.Tag(tagManager).Trace("No user stats updates to commit")
|
|
|
|
|
|
|
+ log.Tag(tag).Trace("No user stats updates to commit")
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
statsQueue := a.statsQueue
|
|
statsQueue := a.statsQueue
|
|
@@ -597,10 +604,10 @@ func (a *Manager) writeUserStatsQueue() error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
defer tx.Rollback()
|
|
defer tx.Rollback()
|
|
|
- log.Tag(tagManager).Debug("Writing user stats queue for %d user(s)", len(statsQueue))
|
|
|
|
|
|
|
+ log.Tag(tag).Debug("Writing user stats queue for %d user(s)", len(statsQueue))
|
|
|
for userID, update := range statsQueue {
|
|
for userID, update := range statsQueue {
|
|
|
log.
|
|
log.
|
|
|
- Tag(tagManager).
|
|
|
|
|
|
|
+ Tag(tag).
|
|
|
Fields(log.Context{
|
|
Fields(log.Context{
|
|
|
"user_id": userID,
|
|
"user_id": userID,
|
|
|
"messages_count": update.Messages,
|
|
"messages_count": update.Messages,
|
|
@@ -618,7 +625,7 @@ func (a *Manager) writeTokenUpdateQueue() error {
|
|
|
a.mu.Lock()
|
|
a.mu.Lock()
|
|
|
if len(a.tokenQueue) == 0 {
|
|
if len(a.tokenQueue) == 0 {
|
|
|
a.mu.Unlock()
|
|
a.mu.Unlock()
|
|
|
- log.Tag(tagManager).Trace("No token updates to commit")
|
|
|
|
|
|
|
+ log.Tag(tag).Trace("No token updates to commit")
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
tokenQueue := a.tokenQueue
|
|
tokenQueue := a.tokenQueue
|
|
@@ -629,9 +636,9 @@ func (a *Manager) writeTokenUpdateQueue() error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
defer tx.Rollback()
|
|
defer tx.Rollback()
|
|
|
- log.Tag(tagManager).Debug("Writing token update queue for %d token(s)", len(tokenQueue))
|
|
|
|
|
|
|
+ log.Tag(tag).Debug("Writing token update queue for %d token(s)", len(tokenQueue))
|
|
|
for tokenID, update := range tokenQueue {
|
|
for tokenID, update := range tokenQueue {
|
|
|
- log.Tag(tagManager).Trace("Updating token %s with last access time %v", tokenID, update.LastAccess.Unix())
|
|
|
|
|
|
|
+ log.Tag(tag).Trace("Updating token %s with last access time %v", tokenID, update.LastAccess.Unix())
|
|
|
if _, err := tx.Exec(updateTokenLastAccessQuery, update.LastAccess.Unix(), update.LastOrigin.String(), tokenID); err != nil {
|
|
if _, err := tx.Exec(updateTokenLastAccessQuery, update.LastAccess.Unix(), update.LastOrigin.String(), tokenID); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -718,7 +725,7 @@ func (a *Manager) MarkUserRemoved(user *User) error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
defer tx.Rollback()
|
|
defer tx.Rollback()
|
|
|
- if _, err := a.db.Exec(deleteUserAccessQuery, user.Name, user.Name); err != nil {
|
|
|
|
|
|
|
+ if _, err := tx.Exec(deleteUserAccessQuery, user.Name, user.Name); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
if _, err := tx.Exec(deleteAllTokenQuery, user.ID); err != nil {
|
|
if _, err := tx.Exec(deleteAllTokenQuery, user.ID); err != nil {
|
|
@@ -1012,7 +1019,6 @@ func (a *Manager) checkReservationsLimit(username string, reservationsLimit int6
|
|
|
|
|
|
|
|
// CheckAllowAccess tests if a user may create an access control entry for the given topic.
|
|
// CheckAllowAccess tests if a user may create an access control entry for the given topic.
|
|
|
// If there are any ACL entries that are not owned by the user, an error is returned.
|
|
// If there are any ACL entries that are not owned by the user, an error is returned.
|
|
|
-// FIXME is this the same as HasReservation?
|
|
|
|
|
func (a *Manager) CheckAllowAccess(username string, topic string) error {
|
|
func (a *Manager) CheckAllowAccess(username string, topic string) error {
|
|
|
if (!AllowedUsername(username) && username != Everyone) || !AllowedTopic(topic) {
|
|
if (!AllowedUsername(username) && username != Everyone) || !AllowedTopic(topic) {
|
|
|
return ErrInvalidArgument
|
|
return ErrInvalidArgument
|
|
@@ -1275,10 +1281,18 @@ func setupDB(db *sql.DB) error {
|
|
|
// Do migrations
|
|
// Do migrations
|
|
|
if schemaVersion == currentSchemaVersion {
|
|
if schemaVersion == currentSchemaVersion {
|
|
|
return nil
|
|
return nil
|
|
|
- } else if schemaVersion == 1 {
|
|
|
|
|
- return migrateFrom1(db)
|
|
|
|
|
|
|
+ } else if schemaVersion > currentSchemaVersion {
|
|
|
|
|
+ return fmt.Errorf("unexpected schema version: version %d is higher than current version %d", schemaVersion, currentSchemaVersion)
|
|
|
|
|
+ }
|
|
|
|
|
+ for i := schemaVersion; i < currentSchemaVersion; i++ {
|
|
|
|
|
+ fn, ok := migrations[i]
|
|
|
|
|
+ if !ok {
|
|
|
|
|
+ return fmt.Errorf("cannot find migration step from schema version %d to %d", i, i+1)
|
|
|
|
|
+ } else if err := fn(db); err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- return fmt.Errorf("unexpected schema version found: %d", schemaVersion)
|
|
|
|
|
|
|
+ return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func setupNewDB(db *sql.DB) error {
|
|
func setupNewDB(db *sql.DB) error {
|
|
@@ -1292,7 +1306,7 @@ func setupNewDB(db *sql.DB) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func migrateFrom1(db *sql.DB) error {
|
|
func migrateFrom1(db *sql.DB) error {
|
|
|
- log.Tag(tagManager).Info("Migrating user database schema: from 1 to 2")
|
|
|
|
|
|
|
+ log.Tag(tag).Info("Migrating user database schema: from 1 to 2")
|
|
|
tx, err := db.Begin()
|
|
tx, err := db.Begin()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
@@ -1339,7 +1353,7 @@ func migrateFrom1(db *sql.DB) error {
|
|
|
if err := tx.Commit(); err != nil {
|
|
if err := tx.Commit(); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- return nil // Update this when a new version is added
|
|
|
|
|
|
|
+ return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func nullString(s string) sql.NullString {
|
|
func nullString(s string) sql.NullString {
|