implement login/logout with session_id

master
Benjamin 'blindCoder' Schieder 2017-04-22 22:22:55 +02:00
parent 44ecb7e512
commit 3b8f8f3b52
5 changed files with 68 additions and 24 deletions

View File

@ -8,15 +8,20 @@ use JSON;
use Tweetodon::Token;
use Data::Dumper;
sub dbTable :lvalue { "invalid"; }
sub orderBy :lvalue { "invalid"; }
sub dbTable :lvalue { "users"; }
sub orderBy :lvalue { "username"; }
# Class functions
sub authenticate {
my $class = shift;
my $instance = $main::FORM{instance};
my $token = $main::FORM{token};
my $session_id = $main::FORM{session_id};
return 0 unless defined($session_id);
my $user = $class->get_by("session_id", $session_id);
return 0 unless $user;
my $instance = $user->{data}->{instance};
my $token = $user->{data}->{access_token};
if ($token){
open(DATA, "./verify_credentials.bash '$token' '$instance'|");
my $reply;
@ -27,11 +32,12 @@ sub authenticate {
close DATA;
$reply = decode_json($reply);
#{"error":"The access token is invalid"}
if (defined($$reply{error})){
if (!defined($$reply{username})){
return 0;
}
$reply->{token} = $token;
$reply->{instance} = $instance;
return $class->new($reply);
#{"id":8225,"username":"b_playsgames","acct":"b_playsgames","display_name":"Ben Plays Games","locked":false,"created_at":"2017-04-18T18:10:51.707Z","followers_count":8,"following_count":0,"statuses_count":13,"note":"Playing games for fun and reduced backlog! Join me at <a href=\\"https://yt.benplaysgames.com/\\" rel=\\"nofollow noopener\\" target=\\"_blank\\"><span class=\\"invisible\\">https://</span><span class=\\"\\">yt.benplaysgames.com/</span><span class=\\"invisible\\"></span></a>","url":"https://toot.berlin/@b_playsgames","avatar":"https://toot.berlin/system/accounts/avatars/000/008/225/original/12899445370222cb.jpg?1492540236","avatar_static":"https://toot.berlin/system/accounts/avatars/000/008/225/original/12899445370222cb.jpg?1492540236","header":"https://toot.berlin/system/accounts/headers/000/008/225/original/0e643b731c89e5a2.jpg?1492540236","header_static":"https://toot.berlin/system/accounts/headers/000/008/225/original/0e643b731c89e5a2.jpg?1492540236"}
}
return 0;
}

View File

@ -5,12 +5,14 @@ use HTML::Template;
use Tweetodon::Website;
use Tweetodon::App;
use Tweetodon::Token;
use Tweetodon::DB;
package Tweetodon::Website::Callback;
@Tweetodon::Website::Callback::ISA = qw(Tweetodon::Website);
use Data::Dumper;
use UUID::Tiny;
use Digest::SHA qw(sha256_base64);
use JSON;
use Tweetodon::DB;
sub requires_authentication {
return 0;
@ -27,7 +29,6 @@ sub prerender {
$self->{"params"}->{"currentmode"} = "Callback";
my $instance = $main::FORM{instance};
my $app = Tweetodon::App->get_or_create_by_instance($instance);
open(DATA, "./process_code.bash '$app->{data}->{instance_client_id}' '$app->{data}->{instance_client_secret}' '$main::FORM{code}' '$main::config->{app}->{redirect_uris}' '$instance'|");
@ -38,10 +39,29 @@ sub prerender {
}
close DATA;
$reply = decode_json($reply);
if (!defined($$reply{access_token})){
main::Error("Login error", "There was an error logging you in!");
return 0;
}
$self->{"set_cookie"} = ("token=".$reply->{access_token});
# Tweetodon::DB->doINSERT("INSERT INTO tokens (access_token, token_type, scope, created_at, username) VALUES (?, ?, ?, ?, ?)", $reply->{access_token}, $reply->{token_type}, $reply->{scope}, $reply->{created_at}, $main::FORM{Username});
#{"access_token":"9615e561d0cf3cb54799ecc381f10b059e781dac2b180e708dcd66683c1cdb81","token_type":"bearer","scope":"read write","created_at":1492718172}
my $token = $$reply{access_token};
open(DATA, "./verify_credentials.bash '$token' '$instance'|");
{
$/ = undef;
$reply = <DATA>
}
close DATA;
$reply = decode_json($reply);
if (!defined($$reply{acct})){
main::Error("Login error", "There was an error logging you in!");
return 0;
}
my $session_id = UUID::Tiny::create_UUID_as_string(UUID_V5, time().$$reply{acct});
Tweetodon::DB->doINSERT("INSERT INTO users (username, username_sha256, instance, instance_sha256, access_token, session_id) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE access_token=?, session_id=?", $$reply{acct}, sha256_base64($$reply{acct}), $instance, sha256_base64($instance), $token, $session_id, $token, $session_id);
$self->{"set_cookie"} = ("session_id=".$session_id);
}
1;

View File

@ -0,0 +1,27 @@
#!/usr/bin/perl -w
use strict;
use HTML::Template;
use Tweetodon::Website;
package Tweetodon::Website::Logout;
@Tweetodon::Website::Logout::ISA = qw(Tweetodon::Website);
sub requires_authentication {
return 0;
}
sub fill_content {
return 1;
}
sub prerender {
my $self = shift;
$self->{"template"} = "Login";
$self->{"content_type"} = "html";
$self->{"params"}->{"currentmode"} = "Login";
$self->{"set_cookie"} = ("session_id=");
}
1;

View File

@ -36,18 +36,9 @@ sub prerender {
$self->{params}->{instance} = $instance;
$self->{params}->{token_is_valid} = "false";
my $token = $main::FORM{token};
if (defined($token)){
#open(DATA, "./verify_credentials.bash '$token' '$instance'|");
#my $reply;
#{
#$/ = undef;
#$reply = <DATA>;
#}
#close DATA;
#$reply = decode_json($reply);
if (Tweetodon::User->authenticate()){
if (defined($main::FORM{session_id})){
my $user = Tweetodon::User->authenticate();
if ($user){
$self->{params}->{token_is_valid} = "true";
}
# {"error":"The access token is invalid"}

View File

@ -120,7 +120,7 @@ my $object;
# TODO: This is a very bad solution but not as bad as an uncontrolled eval...
# The @main::modules array holds a list of all permissible values of the $main::FORM{"mode"} variable.
# If the value is not in this array, the request is not processed and an error is displayed.
my @modules = ("Login", "OAuthLogin", "Dashboard", "Callback", "JSON", "EditFeed");
my @modules = ("Login", "Logout", "OAuthLogin", "Dashboard", "Callback", "JSON", "EditFeed");
if (! grep {$_ eq $FORM{mode}} @modules) {
Error("Validation Error", "$FORM{mode} is not a valid module");