Move DB queries related to 'users' in a separate module (1/2)
This commit is contained in:
parent
92eea3b18b
commit
094f835642
@ -248,7 +248,7 @@ before_all do |env|
|
|||||||
# Invidious users only have SID
|
# Invidious users only have SID
|
||||||
if !env.request.cookies.has_key? "SSID"
|
if !env.request.cookies.has_key? "SSID"
|
||||||
if email = Invidious::Database::SessionIDs.select_email(sid)
|
if email = Invidious::Database::SessionIDs.select_email(sid)
|
||||||
user = PG_DB.query_one("SELECT * FROM users WHERE email = $1", email, as: User)
|
user = Invidious::Database::Users.select!(email: email)
|
||||||
csrf_token = generate_response(sid, {
|
csrf_token = generate_response(sid, {
|
||||||
":authorize_token",
|
":authorize_token",
|
||||||
":playlist_ajax",
|
":playlist_ajax",
|
||||||
@ -458,10 +458,10 @@ post "/watch_ajax" do |env|
|
|||||||
case action
|
case action
|
||||||
when "action_mark_watched"
|
when "action_mark_watched"
|
||||||
if !user.watched.includes? id
|
if !user.watched.includes? id
|
||||||
PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.email)
|
Invidious::Database::Users.mark_watched(user, id)
|
||||||
end
|
end
|
||||||
when "action_mark_unwatched"
|
when "action_mark_unwatched"
|
||||||
PG_DB.exec("UPDATE users SET watched = array_remove(watched, $1) WHERE email = $2", id, user.email)
|
Invidious::Database::Users.mark_unwatched(user, id)
|
||||||
else
|
else
|
||||||
next error_json(400, "Unsupported action #{action}")
|
next error_json(400, "Unsupported action #{action}")
|
||||||
end
|
end
|
||||||
@ -599,16 +599,15 @@ post "/subscription_ajax" do |env|
|
|||||||
# Sync subscriptions with YouTube
|
# Sync subscriptions with YouTube
|
||||||
subscribe_ajax(channel_id, action, env.request.headers)
|
subscribe_ajax(channel_id, action, env.request.headers)
|
||||||
end
|
end
|
||||||
email = user.email
|
|
||||||
|
|
||||||
case action
|
case action
|
||||||
when "action_create_subscription_to_channel"
|
when "action_create_subscription_to_channel"
|
||||||
if !user.subscriptions.includes? channel_id
|
if !user.subscriptions.includes? channel_id
|
||||||
get_channel(channel_id, PG_DB, false, false)
|
get_channel(channel_id, PG_DB, false, false)
|
||||||
PG_DB.exec("UPDATE users SET feed_needs_update = true, subscriptions = array_append(subscriptions, $1) WHERE email = $2", channel_id, email)
|
Invidious::Database::Users.subscribe_channel(user, channel_id)
|
||||||
end
|
end
|
||||||
when "action_remove_subscriptions"
|
when "action_remove_subscriptions"
|
||||||
PG_DB.exec("UPDATE users SET feed_needs_update = true, subscriptions = array_remove(subscriptions, $1) WHERE email = $2", channel_id, email)
|
Invidious::Database::Users.unsubscribe_channel(user, channel_id)
|
||||||
else
|
else
|
||||||
next error_json(400, "Unsupported action #{action}")
|
next error_json(400, "Unsupported action #{action}")
|
||||||
end
|
end
|
||||||
@ -1008,7 +1007,7 @@ post "/delete_account" do |env|
|
|||||||
end
|
end
|
||||||
|
|
||||||
view_name = "subscriptions_#{sha256(user.email)}"
|
view_name = "subscriptions_#{sha256(user.email)}"
|
||||||
PG_DB.exec("DELETE FROM users * WHERE email = $1", user.email)
|
Invidious::Database::Users.delete(user)
|
||||||
Invidious::Database::SessionIDs.delete(email: user.email)
|
Invidious::Database::SessionIDs.delete(email: user.email)
|
||||||
PG_DB.exec("DROP MATERIALIZED VIEW #{view_name}")
|
PG_DB.exec("DROP MATERIALIZED VIEW #{view_name}")
|
||||||
|
|
||||||
@ -1059,7 +1058,7 @@ post "/clear_watch_history" do |env|
|
|||||||
next error_template(400, ex)
|
next error_template(400, ex)
|
||||||
end
|
end
|
||||||
|
|
||||||
PG_DB.exec("UPDATE users SET watched = '{}' WHERE email = $1", user.email)
|
Invidious::Database::Users.clear_watch_history(user)
|
||||||
env.redirect referer
|
env.redirect referer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
129
src/invidious/database/users.cr
Normal file
129
src/invidious/database/users.cr
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
require "./base.cr"
|
||||||
|
|
||||||
|
module Invidious::Database::Users
|
||||||
|
extend self
|
||||||
|
|
||||||
|
# -------------------
|
||||||
|
# Insert / delete
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
def insert(user : User, update_on_conflict : Bool = false)
|
||||||
|
user_array = user.to_a
|
||||||
|
user_array[4] = user_array[4].to_json # User preferences
|
||||||
|
|
||||||
|
request = <<-SQL
|
||||||
|
INSERT INTO users
|
||||||
|
VALUES (#{arg_array(user_array)})
|
||||||
|
SQL
|
||||||
|
|
||||||
|
if update_on_conflict
|
||||||
|
request += <<-SQL
|
||||||
|
ON CONFLICT (email) DO UPDATE
|
||||||
|
SET updated = $1, subscriptions = $3
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
PG_DB.exec(request, args: user_array)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(user : User)
|
||||||
|
request = <<-SQL
|
||||||
|
DELETE FROM users *
|
||||||
|
WHERE email = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
# -------------------
|
||||||
|
# Update (history)
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
def mark_watched(user : User, vid : String)
|
||||||
|
request = <<-SQL
|
||||||
|
UPDATE users
|
||||||
|
SET watched = array_append(watched, $1)
|
||||||
|
WHERE email = $2
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, vid, user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_unwatched(user : User, vid : String)
|
||||||
|
request = <<-SQL
|
||||||
|
UPDATE users
|
||||||
|
SET watched = array_remove(watched, $1)
|
||||||
|
WHERE email = $2
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, vid, user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear_watch_history(user : User)
|
||||||
|
request = <<-SQL
|
||||||
|
UPDATE users
|
||||||
|
SET watched = '{}'
|
||||||
|
WHERE email = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
# -------------------
|
||||||
|
# Update (channels)
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
def subscribe_channel(user : User, ucid : String)
|
||||||
|
request = <<-SQL
|
||||||
|
UPDATE users
|
||||||
|
SET feed_needs_update = true,
|
||||||
|
subscriptions = array_append(subscriptions,$1)
|
||||||
|
WHERE email = $2
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, ucid, user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unsubscribe_channel(user : User, ucid : String)
|
||||||
|
request = <<-SQL
|
||||||
|
UPDATE users
|
||||||
|
SET feed_needs_update = true,
|
||||||
|
subscriptions = array_remove(subscriptions, $1)
|
||||||
|
WHERE email = $2
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, ucid, user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
# -------------------
|
||||||
|
# Select
|
||||||
|
# -------------------
|
||||||
|
|
||||||
|
def select(*, email : String) : User?
|
||||||
|
request = <<-SQL
|
||||||
|
SELECT * FROM users
|
||||||
|
WHERE email = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
return PG_DB.query_one?(request, email, as: User)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Same as select, but can raise an exception
|
||||||
|
def select!(*, email : String) : User
|
||||||
|
request = <<-SQL
|
||||||
|
SELECT * FROM users
|
||||||
|
WHERE email = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
return PG_DB.query_one(request, email, as: User)
|
||||||
|
end
|
||||||
|
|
||||||
|
def select(*, token : String) : User?
|
||||||
|
request = <<-SQL
|
||||||
|
SELECT * FROM users
|
||||||
|
WHERE token = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
return PG_DB.query_one?(request, token, as: User)
|
||||||
|
end
|
||||||
|
end
|
@ -100,7 +100,7 @@ class AuthHandler < Kemal::Handler
|
|||||||
scopes, expire, signature = validate_request(token, session, env.request, HMAC_KEY, PG_DB, nil)
|
scopes, expire, signature = validate_request(token, session, env.request, HMAC_KEY, PG_DB, nil)
|
||||||
|
|
||||||
if email = Invidious::Database::SessionIDs.select_email(session)
|
if email = Invidious::Database::SessionIDs.select_email(session)
|
||||||
user = PG_DB.query_one("SELECT * FROM users WHERE email = $1", email, as: User)
|
user = Invidious::Database::Users.select!(email: email)
|
||||||
end
|
end
|
||||||
elsif sid = env.request.cookies["SID"]?.try &.value
|
elsif sid = env.request.cookies["SID"]?.try &.value
|
||||||
if sid.starts_with? "v1:"
|
if sid.starts_with? "v1:"
|
||||||
@ -108,7 +108,7 @@ class AuthHandler < Kemal::Handler
|
|||||||
end
|
end
|
||||||
|
|
||||||
if email = Invidious::Database::SessionIDs.select_email(sid)
|
if email = Invidious::Database::SessionIDs.select_email(sid)
|
||||||
user = PG_DB.query_one("SELECT * FROM users WHERE email = $1", email, as: User)
|
user = Invidious::Database::Users.select!(email: email)
|
||||||
end
|
end
|
||||||
|
|
||||||
scopes = [":*"]
|
scopes = [":*"]
|
||||||
|
@ -94,7 +94,7 @@ module Invidious::Routes::API::V1::Authenticated
|
|||||||
|
|
||||||
if !user.subscriptions.includes? ucid
|
if !user.subscriptions.includes? ucid
|
||||||
get_channel(ucid, PG_DB, false, false)
|
get_channel(ucid, PG_DB, false, false)
|
||||||
PG_DB.exec("UPDATE users SET feed_needs_update = true, subscriptions = array_append(subscriptions,$1) WHERE email = $2", ucid, user.email)
|
Invidious::Database::Users.subscribe_channel(user, ucid)
|
||||||
end
|
end
|
||||||
|
|
||||||
# For Google accounts, access tokens don't have enough information to
|
# For Google accounts, access tokens don't have enough information to
|
||||||
@ -110,7 +110,7 @@ module Invidious::Routes::API::V1::Authenticated
|
|||||||
|
|
||||||
ucid = env.params.url["ucid"]
|
ucid = env.params.url["ucid"]
|
||||||
|
|
||||||
PG_DB.exec("UPDATE users SET feed_needs_update = true, subscriptions = array_remove(subscriptions, $1) WHERE email = $2", ucid, user.email)
|
Invidious::Database::Users.unsubscribe_channel(user, ucid)
|
||||||
|
|
||||||
env.response.status_code = 204
|
env.response.status_code = 204
|
||||||
end
|
end
|
||||||
|
@ -220,7 +220,7 @@ module Invidious::Routes::Feeds
|
|||||||
haltf env, status_code: 403
|
haltf env, status_code: 403
|
||||||
end
|
end
|
||||||
|
|
||||||
user = PG_DB.query_one?("SELECT * FROM users WHERE token = $1", token.strip, as: User)
|
user = Invidious::Database::Users.select(token: token.strip)
|
||||||
if !user
|
if !user
|
||||||
haltf env, status_code: 403
|
haltf env, status_code: 403
|
||||||
end
|
end
|
||||||
|
@ -327,7 +327,7 @@ module Invidious::Routes::Login
|
|||||||
return error_template(401, "Password is a required field")
|
return error_template(401, "Password is a required field")
|
||||||
end
|
end
|
||||||
|
|
||||||
user = PG_DB.query_one?("SELECT * FROM users WHERE email = $1", email, as: User)
|
user = Invidious::Database::Users.select(email: email)
|
||||||
|
|
||||||
if user
|
if user
|
||||||
if !user.password
|
if !user.password
|
||||||
@ -449,12 +449,7 @@ module Invidious::Routes::Login
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
user_array = user.to_a
|
Invidious::Database::Users.insert(user)
|
||||||
user_array[4] = user_array[4].to_json # User preferences
|
|
||||||
|
|
||||||
args = arg_array(user_array)
|
|
||||||
|
|
||||||
PG_DB.exec("INSERT INTO users VALUES (#{args})", args: user_array)
|
|
||||||
Invidious::Database::SessionIDs.insert(sid, email)
|
Invidious::Database::SessionIDs.insert(sid, email)
|
||||||
|
|
||||||
view_name = "subscriptions_#{sha256(user.email)}"
|
view_name = "subscriptions_#{sha256(user.email)}"
|
||||||
|
@ -76,7 +76,7 @@ module Invidious::Routes::Watch
|
|||||||
env.params.query.delete_all("iv_load_policy")
|
env.params.query.delete_all("iv_load_policy")
|
||||||
|
|
||||||
if watched && !watched.includes? id
|
if watched && !watched.includes? id
|
||||||
PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.as(User).email)
|
Invidious::Database::Users.mark_watched(user.as(User), id)
|
||||||
end
|
end
|
||||||
|
|
||||||
if notifications && notifications.includes? id
|
if notifications && notifications.includes? id
|
||||||
|
@ -31,17 +31,12 @@ end
|
|||||||
|
|
||||||
def get_user(sid, headers, db, refresh = true)
|
def get_user(sid, headers, db, refresh = true)
|
||||||
if email = Invidious::Database::SessionIDs.select_email(sid)
|
if email = Invidious::Database::SessionIDs.select_email(sid)
|
||||||
user = db.query_one("SELECT * FROM users WHERE email = $1", email, as: User)
|
user = Invidious::Database::Users.select!(email: email)
|
||||||
|
|
||||||
if refresh && Time.utc - user.updated > 1.minute
|
if refresh && Time.utc - user.updated > 1.minute
|
||||||
user, sid = fetch_user(sid, headers, db)
|
user, sid = fetch_user(sid, headers, db)
|
||||||
user_array = user.to_a
|
|
||||||
user_array[4] = user_array[4].to_json # User preferences
|
|
||||||
args = arg_array(user_array)
|
|
||||||
|
|
||||||
db.exec("INSERT INTO users VALUES (#{args}) \
|
|
||||||
ON CONFLICT (email) DO UPDATE SET updated = $1, subscriptions = $3", args: user_array)
|
|
||||||
|
|
||||||
|
Invidious::Database::Users.insert(user, update_on_conflict: true)
|
||||||
Invidious::Database::SessionIDs.insert(sid, user.email, handle_conflicts: true)
|
Invidious::Database::SessionIDs.insert(sid, user.email, handle_conflicts: true)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -52,13 +47,8 @@ def get_user(sid, headers, db, refresh = true)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
user, sid = fetch_user(sid, headers, db)
|
user, sid = fetch_user(sid, headers, db)
|
||||||
user_array = user.to_a
|
|
||||||
user_array[4] = user_array[4].to_json # User preferences
|
|
||||||
args = arg_array(user.to_a)
|
|
||||||
|
|
||||||
db.exec("INSERT INTO users VALUES (#{args}) \
|
|
||||||
ON CONFLICT (email) DO UPDATE SET updated = $1, subscriptions = $3", args: user_array)
|
|
||||||
|
|
||||||
|
Invidious::Database::Users.insert(user, update_on_conflict: true)
|
||||||
Invidious::Database::SessionIDs.insert(sid, user.email, handle_conflicts: true)
|
Invidious::Database::SessionIDs.insert(sid, user.email, handle_conflicts: true)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user