master
Benjamin 'blindCoder' Schieder 2017-04-21 21:45:58 +02:00
parent f0de4f8bf5
commit a43f9862bb
17 changed files with 133 additions and 66 deletions

31
Tweetodon/Feed.pm 100644
View File

@ -0,0 +1,31 @@
# vim: set foldmarker={,}:
use strict;
use Tweetodon::Base;
package Tweetodon::Feed;
@Tweetodon::Feed::ISA = qw(Tweetodon::Base);
use JSON;
use Data::Dumper;
sub dbTable :lvalue { "feeds"; }
sub orderBy :lvalue { "url ASC"; }
# Class functions
sub get_by_user_instance {
my $class = shift;
my $user = shift;
my $instance = shift;
my $retVal = Tweetodon::DB->doSELECT("SELECT * FROM ".$class->dbTable." WHERE username = ? AND instance = ? ORDER BY ".$class->orderBy, $user, $instance);
my @retVal;
foreach my $r (@$retVal){
push @retVal, $class->new($r);
}
return @retVal;
}
# Object methods
1;

View File

@ -11,29 +11,6 @@ sub dbTable :lvalue { "tokens"; }
sub orderBy :lvalue { "username ASC"; }
# Class functions
sub get_or_create_by_instance {
my $class = shift;
my $instance = shift;
my $app = Tweetodon::DB->doSELECT("SELECT * FROM apps WHERE instance = ?", $instance);
$app = $$app[0];
unless (defined($app)){
open(DATA, "./register_app.bash '$main::config->{app}->{client_name}' '$main::config->{app}->{redirect_uris}' '$main::config->{app}->{website}' '$instance'|");
my $reply = "";
{
$/ = undef;
$reply = <DATA>;
}
close DATA;
$reply = decode_json($reply);
Tweetodon::DB->doINSERT("INSERT INTO apps (instance, instance_id, instance_client_id, instance_client_secret) VALUES (?, ?, ?, ?)", $instance, $reply->{id}, $reply->{client_id}, $reply->{client_secret});
$app = Tweetodon::DB->doSELECT("SELECT * FROM apps WHERE instance = ?", $instance);
$app = $$app[0];
}
$class->new($app)
}
# Object methods

View File

@ -15,19 +15,16 @@ sub orderBy :lvalue { "invalid"; }
sub authenticate {
my $class = shift;
my $username = $main::FORM{Username};
$username =~ /^(.*?)@(.*)$/;
my $instance = $2;
my $token = Tweetodon::Token->get_by("username", $main::FORM{Username});
my $instance = $main::FORM{instance};
my $token = $main::FORM{token};
if ($token){
open(DATA, "./verify_token.bash '$token->{data}->{access_token}' '$instance'|");
open(DATA, "./verify_credentials.bash '$token' '$instance'|");
my $reply;
{
$/ = undef;
$reply = <DATA>
}
close DATA;
print STDERR "$reply\n";
$reply = decode_json($reply);
#{"error":"The access token is invalid"}
if (defined($$reply{error})){

View File

@ -26,10 +26,7 @@ sub prerender {
$self->{"content_type"} = "html";
$self->{"params"}->{"currentmode"} = "Callback";
my ($user, $instance);
$main::FORM{Username} =~ /^(.*?)@(.*)$/;
$user = $1;
$instance = $2;
my $instance = $main::FORM{instance};
my $app = Tweetodon::App->get_or_create_by_instance($instance);
@ -42,7 +39,8 @@ sub prerender {
close DATA;
$reply = decode_json($reply);
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});
$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}
}

View File

@ -4,6 +4,7 @@
use strict;
use HTML::Template;
use Tweetodon::DB;
use Tweetodon::Feed;
use Tweetodon::Website;
package Tweetodon::Website::Dashboard;
@ -13,11 +14,35 @@ use Data::Dumper;
sub requires_authentication {
return 1;
}
sub fill_content {
my $class = shift;
my $output = shift;
my @feeds = Tweetodon::Feed->get_by_user_instance($main::CURRENTUSER->{data}->{acct}, $main::FORM{instance});
my @param_feeds;
my $count = 0;
foreach my $feed (@feeds){
my %r;
$count++;
$r{"count"} = $count;
foreach my $key (keys %{$feed->{data}}){
$r{$key} = $feed->{data}->{$key};
}
push @param_feeds, \%r;
}
$output->param("FEEDS", \@param_feeds);
return 1;
}
sub prerender {
my $self = shift;
$self->{"template"} = "Dashboard";
$self->{"content_type"} = "html";
$self->{"params"}->{"currentmode"} = "Dashboard";
foreach my $key (keys %{$main::CURRENTUSER->{data}}){
$self->{"params"}->{"acct_$key"} = $main::CURRENTUSER->{data}->{$key};
}
}
1;

View File

@ -155,7 +155,6 @@ sub application_import_accounts {
my @accounts;
foreach my $acc ($a->get_handler()->import_accounts_from_application()){
my %account;
print STDERR Dumper($acc);
$account{"username"} = $$acc{"username"};
$account{"disabled"} = $$acc{"disabled"};
push @accounts, \%account;

View File

@ -5,6 +5,7 @@ use HTML::Template;
use Tweetodon::Website;
use Tweetodon::App;
use Tweetodon::Token;
use Tweetodon::User;
package Tweetodon::Website::OAuthLogin;
@Tweetodon::Website::OAuthLogin::ISA = qw(Tweetodon::Website);
@ -21,24 +22,35 @@ sub fill_content {
sub prerender {
my $self = shift;
my $instance = $main::FORM{inputInstance};
$instance = $main::FORM{instance} unless defined($instance);
$self->{"template"} = "OAuthLogin";
$self->{"content_type"} = "html";
$self->{"set_cookie"} = ("Username=".$main::FORM{inputUsername});
$self->{"set_cookie"} = ("instance=".$instance);
$self->{"params"}->{"currentmode"} = "OAuthLogin";
my ($username, $instance);
$main::FORM{inputUsername} =~ /^(.*?)@(.*)$/;
$username = $1;
$instance = $2;
my $app = Tweetodon::App->get_or_create_by_instance($instance);
my $token = Tweetodon::Token->get_by("username", $main::FORM{inputUsername});
print STDERR Dumper($token);
$self->{params}->{instance_redirect_uri} = $main::config->{app}->{redirect_uris};
$self->{params}->{instance_client_id} = $app->{data}->{instance_client_id};
$self->{params}->{instance} = $instance;
$self->{params}->{token_is_valid} = "false";
unless ($token){
$self->{params}->{instance_redirect_uri} = $main::config->{app}->{redirect_uris};
$self->{params}->{instance_client_id} = $app->{data}->{instance_client_id};
$self->{params}->{instance} = $instance;
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()){
$self->{params}->{token_is_valid} = "true";
}
# {"error":"The access token is invalid"}
}
}

View File

@ -1,4 +1,4 @@
#!/bin/bash
curl -X POST -d "client_id=${1}" -d "client_secret=${2}" -d "grant_type=authorization_code" -d "code=${3}" -d "redirect_uri=${4}" "https://${5}/oauth/token" 2>/dev/null
curl -X POST -d "client_id=${1}" -d "client_secret=${2}" -d "grant_type=authorization_code" -d "code=${3}" -d "redirect_uri=${4}" "${5}/oauth/token" 2>/dev/null
#https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

View File

@ -1,3 +1,3 @@
#!/bin/bash
curl -X POST -d "client_name=${1}" -d "redirect_uris=${2}" -d "scopes=read write" -d "website=${3}" "https://${4}/api/v1/apps" 2>/dev/null
curl -X POST -d "client_name=${1}" -d "redirect_uris=${2}" -d "scopes=read write" -d "website=${3}" "${4}/api/v1/apps" 2>/dev/null

View File

@ -1,6 +1,6 @@
<TMPL_INCLUDE NAME='_header.html'>
<script type="text/javascript">
var l = "index.pl?mode=Dashboard";
var l = "index.pl?mode=OAuthLogin";
document.location.href=l;
</script>
<TMPL_INCLUDE NAME='_footer.html'>

View File

@ -7,8 +7,31 @@
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">Your account</h2>
<div class="row placeholders">
<h4>Foo</h4>
<span class="text-muted">Bar</span>
<h4><TMPL_VAR NAME="acct_acct"></h4>
<table class="table table-hover">
<tbody>
<tr>
<td>User ID</td>
<td><span class="text-muted"><TMPL_VAR NAME="acct_id"></span></td>
</tr>
<tr>
<td>Display name</td>
<td><span class="text-muted"><TMPL_VAR NAME="acct_display_name"></span></td>
</tr>
<tr>
<td>Followers</td>
<td><span class="text-muted"><TMPL_VAR NAME="acct_followers_count"></span></td>
</tr>
<tr>
<td>Following</td>
<td><span class="text-muted"><TMPL_VAR NAME="acct_following_count"></span></td>
</tr>
<tr>
<td>Statuses posted</td>
<td><span class="text-muted"><TMPL_VAR NAME="acct_statuses_count"></span></td>
</tr>
</tbody>
</table>
</div>
<h2 class="sub-header">Your feeds</h2>
@ -21,10 +44,12 @@
</tr>
</thead>
<tbody>
<TMPL_LOOP NAME="FEEDS">
<tr>
<td>123</td>
<td>http://...</td>
<td><TMPL_VAR NAME="count"></td>
<td><TMPL_VAR NAME="url"></td>
</tr>
</TMPL_LOOP>
</tbody>
</table>
</div>

View File

@ -2,9 +2,9 @@
<div class="container">
<form class="form-signin" method="POST" action="index.pl">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputUsername" class="sr-only">Username</label>
<input type="username" id="inputUsername" name="inputUsername" class="form-control" placeholder="username@mastodon.social" required autofocus>
<h2 class="form-signin-heading">Please enter your Mastodon instance URL</h2>
<label for="inputUsername" class="sr-only">Mastodon instance URL</label>
<input type="url" id="inputInstance" name="inputInstance" class="form-control" placeholder="mastodon.social" required autofocus>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<input type="hidden" id="mode" name="mode" value="OAuthLogin">

View File

@ -1,6 +1,11 @@
<TMPL_INCLUDE NAME='_header.html'>
<script type="text/javascript">
var l = "https://<TMPL_VAR NAME='instance'>/oauth/authorize?response_type=code&client_id=<TMPL_VAR NAME='instance_client_id'>&redirect_uri="+encodeURIComponent("<TMPL_VAR NAME='instance_redirect_uri'>")+"&scope=read%20write";
var l;
if ("<TMPL_VAR NAME='token_is_valid'>" == "true"){
l = "index.pl?mode=Dashboard";
} else {
l = "<TMPL_VAR NAME='instance'>/oauth/authorize?response_type=code&client_id=<TMPL_VAR NAME='instance_client_id'>&redirect_uri="+encodeURIComponent("<TMPL_VAR NAME='instance_redirect_uri'>")+"&scope=read%20write";
}
document.location.href=l;
</script>
<TMPL_INCLUDE NAME='_footer.html'>

View File

@ -20,5 +20,4 @@
<script src="static/js/<TMPL_VAR NAME='currentmode'>.js"></script>
</head>
<body>
<input type='hidden' id='session_uuid' value="<TMPL_VAR NAME='currentuser.session_uuid'>"><!-- This is for some external scripts -->
<input type='hidden' id='currentmode' value="<TMPL_VAR NAME='currentmode'>"><!-- This is for some external scripts -->

View File

@ -11,8 +11,7 @@
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="index.pl?mode=Settings&session_uuid=<TMPL_VAR NAME="currentuser.session_uuid">">Settings</a></li>
<li><a href="index.pl?mode=Logout&session_uuid=<TMPL_VAR NAME="currentuser.session_uuid">">Logout</a></li>
<li><a href="index.pl?mode=Logout">Logout</a></li>
</ul>
</div>
</div>

View File

@ -0,0 +1,5 @@
#!/bin/bash
echo curl -X GET --header "Authorization: Bearer ${1}" "${2}/api/v1/accounts/verify_credentials" >&2
curl -X GET --header "Authorization: Bearer ${1}" "${2}/api/v1/accounts/verify_credentials" 2>/dev/null
#https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

View File

@ -1,5 +0,0 @@
#!/bin/bash
echo curl -X GET --header "Authorization: Bearer ${1}" "https://${2}/api/v1/accounts/verify_credentials" >&2
curl -X GET --header "Authorization: Bearer ${1}" "https://${2}/api/v1/accounts/verify_credentials" 2>/dev/null
#https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL