mirror of
https://codeberg.org/shroff/phylum.git
synced 2025-12-31 08:20:09 -06:00
[server][breaking] Change pending logins table schema, add token expiration
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user