Skip to content

Commit 85ba04b

Browse files
authored
Merge pull request #2871 from SamantazFox/user-code-cleaning
User code cleaning & fixing
2 parents 8af202e + 57353fe commit 85ba04b

24 files changed

+803
-666
lines changed

spec/invidious/user/imports_spec.cr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ def csv_sample
2525
CSV
2626
end
2727

28-
Spectator.describe "Invidious::User::Imports" do
28+
Spectator.describe Invidious::User::Import do
2929
it "imports CSV" do
30-
subscriptions = parse_subscription_export_csv(csv_sample)
30+
subscriptions = Invidious::User::Import.parse_subscription_export_csv(csv_sample)
3131

3232
expect(subscriptions).to be_an(Array(String))
3333
expect(subscriptions.size).to eq(13)

src/invidious.cr

Lines changed: 10 additions & 337 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@ require "./invidious/jobs/**"
3838
CONFIG = Config.load
3939
HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
4040

41-
PG_DB = DB.open CONFIG.database_url
42-
ARCHIVE_URL = URI.parse("https://archive.org")
43-
LOGIN_URL = URI.parse("https://accounts.google.com")
44-
PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
45-
REDDIT_URL = URI.parse("https://www.reddit.com")
46-
TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com")
47-
YT_URL = URI.parse("https://www.youtube.com")
48-
HOST_URL = make_host_url(Kemal.config)
41+
PG_DB = DB.open CONFIG.database_url
42+
ARCHIVE_URL = URI.parse("https://archive.org")
43+
LOGIN_URL = URI.parse("https://accounts.google.com")
44+
PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
45+
REDDIT_URL = URI.parse("https://www.reddit.com")
46+
YT_URL = URI.parse("https://www.youtube.com")
47+
HOST_URL = make_host_url(Kemal.config)
4948

5049
CHARS_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
5150
TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk", "iqKdEhx-dD4"}
@@ -366,15 +365,8 @@ end
366365
Invidious::Routing.get "/results", Invidious::Routes::Search, :results
367366
Invidious::Routing.get "/search", Invidious::Routes::Search, :search
368367

369-
Invidious::Routing.get "/login", Invidious::Routes::Login, :login_page
370-
Invidious::Routing.post "/login", Invidious::Routes::Login, :login
371-
Invidious::Routing.post "/signout", Invidious::Routes::Login, :signout
372-
373-
Invidious::Routing.get "/preferences", Invidious::Routes::PreferencesRoute, :show
374-
Invidious::Routing.post "/preferences", Invidious::Routes::PreferencesRoute, :update
375-
Invidious::Routing.get "/toggle_theme", Invidious::Routes::PreferencesRoute, :toggle_theme
376-
Invidious::Routing.get "/data_control", Invidious::Routes::PreferencesRoute, :data_control
377-
Invidious::Routing.post "/data_control", Invidious::Routes::PreferencesRoute, :update_data_control
368+
# User routes
369+
define_user_routes()
378370

379371
# Feeds
380372
Invidious::Routing.get "/view_all_playlists", Invidious::Routes::Feeds, :view_all_playlists_redirect
@@ -414,325 +406,6 @@ define_v1_api_routes()
414406
define_api_manifest_routes()
415407
define_video_playback_routes()
416408

417-
get "/change_password" do |env|
418-
locale = env.get("preferences").as(Preferences).locale
419-
420-
user = env.get? "user"
421-
sid = env.get? "sid"
422-
referer = get_referer(env)
423-
424-
if !user
425-
next env.redirect referer
426-
end
427-
428-
user = user.as(User)
429-
sid = sid.as(String)
430-
csrf_token = generate_response(sid, {":change_password"}, HMAC_KEY)
431-
432-
templated "change_password"
433-
end
434-
435-
post "/change_password" do |env|
436-
locale = env.get("preferences").as(Preferences).locale
437-
438-
user = env.get? "user"
439-
sid = env.get? "sid"
440-
referer = get_referer(env)
441-
442-
if !user
443-
next env.redirect referer
444-
end
445-
446-
user = user.as(User)
447-
sid = sid.as(String)
448-
token = env.params.body["csrf_token"]?
449-
450-
# We don't store passwords for Google accounts
451-
if !user.password
452-
next error_template(400, "Cannot change password for Google accounts")
453-
end
454-
455-
begin
456-
validate_request(token, sid, env.request, HMAC_KEY, locale)
457-
rescue ex
458-
next error_template(400, ex)
459-
end
460-
461-
password = env.params.body["password"]?
462-
if !password
463-
next error_template(401, "Password is a required field")
464-
end
465-
466-
new_passwords = env.params.body.select { |k, v| k.match(/^new_password\[\d+\]$/) }.map { |k, v| v }
467-
468-
if new_passwords.size <= 1 || new_passwords.uniq.size != 1
469-
next error_template(400, "New passwords must match")
470-
end
471-
472-
new_password = new_passwords.uniq[0]
473-
if new_password.empty?
474-
next error_template(401, "Password cannot be empty")
475-
end
476-
477-
if new_password.bytesize > 55
478-
next error_template(400, "Password cannot be longer than 55 characters")
479-
end
480-
481-
if !Crypto::Bcrypt::Password.new(user.password.not_nil!).verify(password.byte_slice(0, 55))
482-
next error_template(401, "Incorrect password")
483-
end
484-
485-
new_password = Crypto::Bcrypt::Password.create(new_password, cost: 10)
486-
Invidious::Database::Users.update_password(user, new_password.to_s)
487-
488-
env.redirect referer
489-
end
490-
491-
get "/delete_account" do |env|
492-
locale = env.get("preferences").as(Preferences).locale
493-
494-
user = env.get? "user"
495-
sid = env.get? "sid"
496-
referer = get_referer(env)
497-
498-
if !user
499-
next env.redirect referer
500-
end
501-
502-
user = user.as(User)
503-
sid = sid.as(String)
504-
csrf_token = generate_response(sid, {":delete_account"}, HMAC_KEY)
505-
506-
templated "delete_account"
507-
end
508-
509-
post "/delete_account" do |env|
510-
locale = env.get("preferences").as(Preferences).locale
511-
512-
user = env.get? "user"
513-
sid = env.get? "sid"
514-
referer = get_referer(env)
515-
516-
if !user
517-
next env.redirect referer
518-
end
519-
520-
user = user.as(User)
521-
sid = sid.as(String)
522-
token = env.params.body["csrf_token"]?
523-
524-
begin
525-
validate_request(token, sid, env.request, HMAC_KEY, locale)
526-
rescue ex
527-
next error_template(400, ex)
528-
end
529-
530-
view_name = "subscriptions_#{sha256(user.email)}"
531-
Invidious::Database::Users.delete(user)
532-
Invidious::Database::SessionIDs.delete(email: user.email)
533-
PG_DB.exec("DROP MATERIALIZED VIEW #{view_name}")
534-
535-
env.request.cookies.each do |cookie|
536-
cookie.expires = Time.utc(1990, 1, 1)
537-
env.response.cookies << cookie
538-
end
539-
540-
env.redirect referer
541-
end
542-
543-
get "/clear_watch_history" do |env|
544-
locale = env.get("preferences").as(Preferences).locale
545-
546-
user = env.get? "user"
547-
sid = env.get? "sid"
548-
referer = get_referer(env)
549-
550-
if !user
551-
next env.redirect referer
552-
end
553-
554-
user = user.as(User)
555-
sid = sid.as(String)
556-
csrf_token = generate_response(sid, {":clear_watch_history"}, HMAC_KEY)
557-
558-
templated "clear_watch_history"
559-
end
560-
561-
post "/clear_watch_history" do |env|
562-
locale = env.get("preferences").as(Preferences).locale
563-
564-
user = env.get? "user"
565-
sid = env.get? "sid"
566-
referer = get_referer(env)
567-
568-
if !user
569-
next env.redirect referer
570-
end
571-
572-
user = user.as(User)
573-
sid = sid.as(String)
574-
token = env.params.body["csrf_token"]?
575-
576-
begin
577-
validate_request(token, sid, env.request, HMAC_KEY, locale)
578-
rescue ex
579-
next error_template(400, ex)
580-
end
581-
582-
Invidious::Database::Users.clear_watch_history(user)
583-
env.redirect referer
584-
end
585-
586-
get "/authorize_token" do |env|
587-
locale = env.get("preferences").as(Preferences).locale
588-
589-
user = env.get? "user"
590-
sid = env.get? "sid"
591-
referer = get_referer(env)
592-
593-
if !user
594-
next env.redirect referer
595-
end
596-
597-
user = user.as(User)
598-
sid = sid.as(String)
599-
csrf_token = generate_response(sid, {":authorize_token"}, HMAC_KEY)
600-
601-
scopes = env.params.query["scopes"]?.try &.split(",")
602-
scopes ||= [] of String
603-
604-
callback_url = env.params.query["callback_url"]?
605-
if callback_url
606-
callback_url = URI.parse(callback_url)
607-
end
608-
609-
expire = env.params.query["expire"]?.try &.to_i?
610-
611-
templated "authorize_token"
612-
end
613-
614-
post "/authorize_token" do |env|
615-
locale = env.get("preferences").as(Preferences).locale
616-
617-
user = env.get? "user"
618-
sid = env.get? "sid"
619-
referer = get_referer(env)
620-
621-
if !user
622-
next env.redirect referer
623-
end
624-
625-
user = env.get("user").as(User)
626-
sid = sid.as(String)
627-
token = env.params.body["csrf_token"]?
628-
629-
begin
630-
validate_request(token, sid, env.request, HMAC_KEY, locale)
631-
rescue ex
632-
next error_template(400, ex)
633-
end
634-
635-
scopes = env.params.body.select { |k, v| k.match(/^scopes\[\d+\]$/) }.map { |k, v| v }
636-
callback_url = env.params.body["callbackUrl"]?
637-
expire = env.params.body["expire"]?.try &.to_i?
638-
639-
access_token = generate_token(user.email, scopes, expire, HMAC_KEY)
640-
641-
if callback_url
642-
access_token = URI.encode_www_form(access_token)
643-
url = URI.parse(callback_url)
644-
645-
if url.query
646-
query = HTTP::Params.parse(url.query.not_nil!)
647-
else
648-
query = HTTP::Params.new
649-
end
650-
651-
query["token"] = access_token
652-
url.query = query.to_s
653-
654-
env.redirect url.to_s
655-
else
656-
csrf_token = ""
657-
env.set "access_token", access_token
658-
templated "authorize_token"
659-
end
660-
end
661-
662-
get "/token_manager" do |env|
663-
locale = env.get("preferences").as(Preferences).locale
664-
665-
user = env.get? "user"
666-
sid = env.get? "sid"
667-
referer = get_referer(env, "/subscription_manager")
668-
669-
if !user
670-
next env.redirect referer
671-
end
672-
673-
user = user.as(User)
674-
tokens = Invidious::Database::SessionIDs.select_all(user.email)
675-
676-
templated "token_manager"
677-
end
678-
679-
post "/token_ajax" do |env|
680-
locale = env.get("preferences").as(Preferences).locale
681-
682-
user = env.get? "user"
683-
sid = env.get? "sid"
684-
referer = get_referer(env)
685-
686-
redirect = env.params.query["redirect"]?
687-
redirect ||= "true"
688-
redirect = redirect == "true"
689-
690-
if !user
691-
if redirect
692-
next env.redirect referer
693-
else
694-
next error_json(403, "No such user")
695-
end
696-
end
697-
698-
user = user.as(User)
699-
sid = sid.as(String)
700-
token = env.params.body["csrf_token"]?
701-
702-
begin
703-
validate_request(token, sid, env.request, HMAC_KEY, locale)
704-
rescue ex
705-
if redirect
706-
next error_template(400, ex)
707-
else
708-
next error_json(400, ex)
709-
end
710-
end
711-
712-
if env.params.query["action_revoke_token"]?
713-
action = "action_revoke_token"
714-
else
715-
next env.redirect referer
716-
end
717-
718-
session = env.params.query["session"]?
719-
session ||= ""
720-
721-
case action
722-
when .starts_with? "action_revoke_token"
723-
Invidious::Database::SessionIDs.delete(sid: session, email: user.email)
724-
else
725-
next error_json(400, "Unsupported action #{action}")
726-
end
727-
728-
if redirect
729-
env.redirect referer
730-
else
731-
env.response.content_type = "application/json"
732-
"{}"
733-
end
734-
end
735-
736409
# Channels
737410

738411
{"/channel/:ucid/live", "/user/:user/live", "/c/:user/live"}.each do |route|
@@ -876,7 +549,7 @@ add_handler AuthHandler.new
876549
add_handler DenyFrame.new
877550
add_context_storage_type(Array(String))
878551
add_context_storage_type(Preferences)
879-
add_context_storage_type(User)
552+
add_context_storage_type(Invidious::User)
880553

881554
Kemal.config.logger = LOGGER
882555
Kemal.config.host_binding = Kemal.config.host_binding != "0.0.0.0" ? Kemal.config.host_binding : CONFIG.host_binding

0 commit comments

Comments
 (0)