[server][breaking] Change pending logins table schema, add token expiration

This commit is contained in:
Abhishek Shroff
2025-07-09 01:12:53 +05:30
parent e3142e7f7a
commit 1a152d819d
3 changed files with 22 additions and 7 deletions

View File

@@ -4,6 +4,7 @@ import (
"errors"
"net/url"
"strings"
"time"
"codeberg.org/shroff/phylum/server/internal/auth/openid"
"codeberg.org/shroff/phylum/server/internal/core"
@@ -24,7 +25,15 @@ func OpenIDStart(db db.Handler, providerName, redirectURI string, clientType Ope
return "", err
} else {
token := generateSecureKey(loginTokenLength)
_, err := db.Exec("INSERT INTO pending_logins(token, oidc_provider, oidc_client_type) VALUES ($1, $2, $3)", token, providerName, clientType)
args := pgx.NamedArgs{
"token": token,
"expires": time.Now().Add(resetTokenDuration),
"oidc_provider": providerName,
"oidc_client_type": clientType,
}
const query = `INSERT INTO pending_logins(token, expires, oidc_provider, oidc_client_type)
VALUES (@token::TEXT, @expires::TIMESTAMPTZ, @oidc_provider::TEXT, @oidc_client_type::SMALLINT)`
_, err := db.Exec(query, args)
if err != nil {
return "", errors.New("failed to create login token: " + err.Error())
}
@@ -32,6 +41,7 @@ func OpenIDStart(db db.Handler, providerName, redirectURI string, clientType Ope
if err != nil {
return "", errors.New("failed to parse authoriation endpoint: " + err.Error())
}
q := url.Values{}
q.Add("client_id", clientID)
q.Add("response_type", "code")
@@ -44,7 +54,7 @@ func OpenIDStart(db db.Handler, providerName, redirectURI string, clientType Ope
}
func OpenIDValidateAuthCode(d db.Handler, token, authCode, redirecURI string) (OpenIDClientType, error) {
row := d.QueryRow("SELECT oidc_provider, oidc_client_type FROM pending_logins WHERE token = $1 AND user_id IS NULL", token)
row := d.QueryRow("SELECT oidc_provider, oidc_client_type FROM pending_logins WHERE token = $1 AND user_id IS NULL AND expires >= NOW()", token)
var providerName string
var clientType OpenIDClientType
if err := row.Scan(&providerName, &clientType); err != nil {

View File

@@ -2,6 +2,8 @@ package auth
import (
"errors"
"net/http"
"time"
"codeberg.org/shroff/phylum/server/internal/core"
"codeberg.org/shroff/phylum/server/internal/db"
@@ -9,13 +11,16 @@ import (
)
func PerformTokenLogin(db db.TxHandler, token string) (core.User, string, error) {
row := db.QueryRow("DELETE FROM pending_logins WHERE token = $1 AND user_id IS NOT NULL RETURNING user_id", token)
row := db.QueryRow("DELETE FROM pending_logins WHERE token = $1 AND user_id IS NOT NULL RETURNING user_id, expires", token)
var userID int32
if err := row.Scan(&userID); err != nil {
var expires time.Time
if err := row.Scan(&userID, &expires); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
err = errors.New("login token invalid")
err = core.NewError(http.StatusBadRequest, "login_token_invalid", "The given login token is invalid")
}
return core.User{}, "", err
} else if expires.Before(time.Now()) {
return core.User{}, "", core.NewError(http.StatusBadRequest, "login_token_invalid", "The given login token is invalid")
} else if user, err := core.UserByID(db, userID); err != nil {
return core.User{}, "", err
} else if token, err := insertAPIKey(db, userID); err != nil {

View File

@@ -1,6 +1,6 @@
CREATE UNLOGGED TABLE pending_logins(
CREATE TABLE pending_logins(
token TEXT PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires TIMESTAMPTZ NOT NULL,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
oidc_provider TEXT,
oidc_client_type SMALLINT