]> git.mxchange.org Git - friendica.git/commitdiff
Repurposed OAuth frontend handling, store the scope
authorMichael <heluecht@pirati.ca>
Thu, 13 May 2021 14:58:55 +0000 (14:58 +0000)
committerMichael <heluecht@pirati.ca>
Thu, 13 May 2021 14:58:55 +0000 (14:58 +0000)
database.sql
mod/settings.php
src/Module/Api/Mastodon/Apps.php
src/Module/BaseApi.php
src/Module/OAuth/Authorize.php
static/dbstructure.config.php
static/dbview.config.php
view/templates/settings/oauth.tpl
view/theme/frio/templates/settings/oauth.tpl

index bbcd479bc9a24c8301a29f4fc77e86d82e5ac134..99386abf4572f33895d0be8e2de4eef8a689703f 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2021.06-dev (Siberian Iris)
--- DB_UPDATE_VERSION 1416
+-- DB_UPDATE_VERSION 1417
 -- ------------------------------------------
 
 
@@ -375,6 +375,9 @@ CREATE TABLE IF NOT EXISTS `application` (
        `redirect_uri` varchar(255) NOT NULL COMMENT '',
        `website` varchar(255) COMMENT '',
        `scopes` varchar(255) COMMENT '',
+       `read` boolean COMMENT 'Read scope',
+       `write` boolean COMMENT 'Write scope',
+       `follow` boolean COMMENT 'Follow scope',
         PRIMARY KEY(`id`),
         UNIQUE INDEX `client_id` (`client_id`)
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='OAuth application';
@@ -387,7 +390,11 @@ CREATE TABLE IF NOT EXISTS `application-token` (
        `uid` mediumint unsigned NOT NULL COMMENT 'Owner User id',
        `code` varchar(64) NOT NULL COMMENT '',
        `access_token` varchar(64) NOT NULL COMMENT '',
-       `created_at` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'creation time',
+       `created_at` datetime NOT NULL COMMENT 'creation time',
+       `scopes` varchar(255) COMMENT '',
+       `read` boolean COMMENT 'Read scope',
+       `write` boolean COMMENT 'Write scope',
+       `follow` boolean COMMENT 'Follow scope',
         PRIMARY KEY(`application-id`,`uid`),
         INDEX `uid_id` (`uid`,`application-id`),
        FOREIGN KEY (`application-id`) REFERENCES `application` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
@@ -1500,6 +1507,27 @@ CREATE TABLE IF NOT EXISTS `workerqueue` (
         INDEX `done_pid_priority_created` (`done`,`pid`,`priority`,`created`)
 ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Background tasks queue entries';
 
+--
+-- VIEW application-view
+--
+DROP VIEW IF EXISTS `application-view`;
+CREATE VIEW `application-view` AS SELECT 
+       `application`.`id` AS `id`,
+       `application-token`.`uid` AS `uid`,
+       `application`.`name` AS `name`,
+       `application`.`redirect_uri` AS `redirect_uri`,
+       `application`.`website` AS `website`,
+       `application`.`client_id` AS `client_id`,
+       `application`.`client_secret` AS `client_secret`,
+       `application-token`.`code` AS `code`,
+       `application-token`.`access_token` AS `access_token`,
+       `application-token`.`created_at` AS `created_at`,
+       `application-token`.`scopes` AS `scopes`,
+       `application-token`.`read` AS `read`,
+       `application-token`.`write` AS `write`,
+       `application-token`.`follow` AS `follow`
+       FROM `application-token` INNER JOIN `application` ON `application-token`.`application-id` = `application`.`id`;
+
 --
 -- VIEW post-user-view
 --
index c8dbcb9105bf4443d67d1aa711f8159af46909d5..3a3f0b65dccf974004433a96c4a0dff60a1e1555 100644 (file)
@@ -500,77 +500,26 @@ function settings_content(App $a)
        }
 
        if (($a->argc > 1) && ($a->argv[1] === 'oauth')) {
-               if (($a->argc > 2) && ($a->argv[2] === 'add')) {
-                       $tpl = Renderer::getMarkupTemplate('settings/oauth_edit.tpl');
-                       $o .= Renderer::replaceMacros($tpl, [
-                               '$form_security_token' => BaseModule::getFormSecurityToken("settings_oauth"),
-                               '$title'        => DI::l10n()->t('Add application'),
-                               '$submit'       => DI::l10n()->t('Save Settings'),
-                               '$cancel'       => DI::l10n()->t('Cancel'),
-                               '$name'         => ['name', DI::l10n()->t('Name'), '', ''],
-                               '$key'          => ['key', DI::l10n()->t('Consumer Key'), '', ''],
-                               '$secret'       => ['secret', DI::l10n()->t('Consumer Secret'), '', ''],
-                               '$redirect'     => ['redirect', DI::l10n()->t('Redirect'), '', ''],
-                               '$icon'         => ['icon', DI::l10n()->t('Icon url'), '', ''],
-                       ]);
-                       return $o;
-               }
-
-               if (($a->argc > 3) && ($a->argv[2] === 'edit')) {
-                       $r = q("SELECT * FROM clients WHERE client_id='%s' AND uid=%d",
-                                       DBA::escape($a->argv[3]),
-                                       local_user());
-
-                       if (!DBA::isResult($r)) {
-                               notice(DI::l10n()->t("You can't edit this application."));
-                               return;
-                       }
-                       $app = $r[0];
-
-                       $tpl = Renderer::getMarkupTemplate('settings/oauth_edit.tpl');
-                       $o .= Renderer::replaceMacros($tpl, [
-                               '$form_security_token' => BaseModule::getFormSecurityToken("settings_oauth"),
-                               '$title'        => DI::l10n()->t('Add application'),
-                               '$submit'       => DI::l10n()->t('Update'),
-                               '$cancel'       => DI::l10n()->t('Cancel'),
-                               '$name'         => ['name', DI::l10n()->t('Name'), $app['name'] , ''],
-                               '$key'          => ['key', DI::l10n()->t('Consumer Key'), $app['client_id'], ''],
-                               '$secret'       => ['secret', DI::l10n()->t('Consumer Secret'), $app['pw'], ''],
-                               '$redirect'     => ['redirect', DI::l10n()->t('Redirect'), $app['redirect_uri'], ''],
-                               '$icon'         => ['icon', DI::l10n()->t('Icon url'), $app['icon'], ''],
-                       ]);
-                       return $o;
-               }
-
                if (($a->argc > 3) && ($a->argv[2] === 'delete')) {
                        BaseModule::checkFormSecurityTokenRedirectOnError('/settings/oauth', 'settings_oauth', 't');
 
-                       DBA::delete('clients', ['client_id' => $a->argv[3], 'uid' => local_user()]);
+                       DBA::delete('application-token', ['application-id' => $a->argv[3], 'uid' => local_user()]);
                        DI::baseUrl()->redirect('settings/oauth/', true);
                        return;
                }
 
-               /// @TODO validate result with DBA::isResult()
-               $r = q("SELECT clients.*, tokens.id as oauth_token, (clients.uid=%d) AS my
-                               FROM clients
-                               LEFT JOIN tokens ON clients.client_id=tokens.client_id
-                               WHERE clients.uid IN (%d, 0)",
-                               local_user(),
-                               local_user());
-
+               $applications = DBA::selectToArray('application-view', ['id', 'uid', 'name', 'website', 'scopes', 'created_at'], ['uid' => local_user()]);
 
                $tpl = Renderer::getMarkupTemplate('settings/oauth.tpl');
                $o .= Renderer::replaceMacros($tpl, [
                        '$form_security_token' => BaseModule::getFormSecurityToken("settings_oauth"),
-                       '$baseurl'      => DI::baseUrl()->get(true),
-                       '$title'        => DI::l10n()->t('Connected Apps'),
-                       '$add'          => DI::l10n()->t('Add application'),
-                       '$edit'         => DI::l10n()->t('Edit'),
-                       '$delete'               => DI::l10n()->t('Delete'),
-                       '$consumerkey' => DI::l10n()->t('Client key starts with'),
-                       '$noname'       => DI::l10n()->t('No name'),
-                       '$remove'       => DI::l10n()->t('Remove authorization'),
-                       '$apps'         => $r,
+                       '$baseurl'             => DI::baseUrl()->get(true),
+                       '$title'               => DI::l10n()->t('Connected Apps'),
+                       '$name'                => DI::l10n()->t('Name'),
+                       '$website'             => DI::l10n()->t('Home Page'),
+                       '$created_at'          => DI::l10n()->t('Created'),
+                       '$delete'              => DI::l10n()->t('Remove authorization'),
+                       '$apps'                => $applications,
                ]);
                return $o;
        }
index 0fc206d43bd84c5874963ac88a4e66d29e5cbf55..8205691dca47c9c0d133249e6237d0d19a3ab5f1 100644 (file)
@@ -51,7 +51,7 @@ class Apps extends BaseApi
 
                $name     = $_REQUEST['client_name'] ?? '';
                $redirect = $_REQUEST['redirect_uris'] ?? '';
-               $scopes   = $_REQUEST['scopes'] ?? '';
+               $scopes   = $_REQUEST['scopes'] ?? 'read';
                $website  = $_REQUEST['website'] ?? '';
 
                if (empty($name) || empty($redirect)) {
@@ -67,6 +67,10 @@ class Apps extends BaseApi
                        $fields['scopes'] = $scopes;
                }
 
+               $fields['read']   = (stripos($scopes, 'read') !== false);
+               $fields['write']  = (stripos($scopes, 'write') !== false);
+               $fields['follow'] = (stripos($scopes, 'follow') !== false);
+
                if (!empty($website)) {
                        $fields['website'] = $website;
                }
index 6c2f13c59062655a53631606bf74320df3e81b45..a53c008c62cf7e9b57e85f4208dd30f6158e9e28 100644 (file)
@@ -267,9 +267,9 @@ class BaseApi extends BaseModule
                $code         = bin2hex(random_bytes(32));
                $access_token = bin2hex(random_bytes(32));
 
-               // @todo store the scope
-
-               $fields = ['application-id' => $application['id'], 'uid' => $uid, 'code' => $code, 'access_token' => $access_token, 'created_at' => DateTimeFormat::utcNow(DateTimeFormat::MYSQL)];
+               $fields = ['application-id' => $application['id'], 'uid' => $uid, 'code' => $code, 'access_token' => $access_token, 'scopes' => $scope,
+                       'read' => (stripos($scope, 'read') !== false), 'write' => (stripos($scope, 'write') !== false),
+                       'follow' => (stripos($scope, 'follow') !== false), 'created_at' => DateTimeFormat::utcNow(DateTimeFormat::MYSQL)];
                if (!DBA::insert('application-token', $fields, Database::INSERT_UPDATE)) {
                        return [];
                }
index c9562077059f51cae6650a0aabb36211e66176e2..57efe70c6387409bf16c780a333321c7351c4ec2 100644 (file)
@@ -41,7 +41,7 @@ class Authorize extends BaseApi
                $client_id     = $_REQUEST['client_id'] ?? '';
                $client_secret = $_REQUEST['client_secret'] ?? ''; // Isn't normally provided. We will use it if present.
                $redirect_uri  = $_REQUEST['redirect_uri'] ?? '';
-               $scope         = $_REQUEST['scope'] ?? '';
+               $scope         = $_REQUEST['scope'] ?? 'read';
                $state         = $_REQUEST['state'] ?? '';
 
                if ($response_type != 'code') {
index 41515681e4a17a9050d624f13001a885f18e82a7..a074ef0b82cf35ebc0a6fbe94a979fae40409282 100644 (file)
@@ -55,7 +55,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1416);
+       define('DB_UPDATE_VERSION', 1417);
 }
 
 return [
@@ -436,6 +436,9 @@ return [
                        "redirect_uri" => ["type" => "varchar(255)", "not null" => "1", "comment" => ""],
                        "website" => ["type" => "varchar(255)", "comment" => ""],
                        "scopes" => ["type" => "varchar(255)", "comment" => ""],
+                       "read" => ["type" => "boolean", "comment" => "Read scope"],
+                       "write" => ["type" => "boolean", "comment" => "Write scope"],
+                       "follow" => ["type" => "boolean", "comment" => "Follow scope"],
                ],
                "indexes" => [
                        "PRIMARY" => ["id"],
@@ -449,7 +452,11 @@ return [
                        "uid" => ["type" => "mediumint unsigned", "not null" => "1", "primary" => "1", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
                        "code" => ["type" => "varchar(64)", "not null" => "1", "comment" => ""],
                        "access_token" => ["type" => "varchar(64)", "not null" => "1", "comment" => ""],
-                       "created_at" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "creation time"],
+                       "created_at" => ["type" => "datetime", "not null" => "1", "comment" => "creation time"],
+                       "scopes" => ["type" => "varchar(255)", "comment" => ""],
+                       "read" => ["type" => "boolean", "comment" => "Read scope"],
+                       "write" => ["type" => "boolean", "comment" => "Write scope"],
+                       "follow" => ["type" => "boolean", "comment" => "Follow scope"],
                ],
                "indexes" => [
                        "PRIMARY" => ["application-id", "uid"],
index 94b81411b4f8707e4746674bf76e229879cec40f..f8ebc05720ef0207646c2b8dfdd7d95f2c8d1b67 100644 (file)
  */
 
  return [
+       "application-view" => [
+               "fields" => [
+                       "id" => ["application", "id"],
+                       "uid" => ["application-token", "uid"],
+                       "name" => ["application", "name"],
+                       "redirect_uri" => ["application", "redirect_uri"],
+                       "website" => ["application", "website"],
+                       "client_id" => ["application", "client_id"],
+                       "client_secret" => ["application", "client_secret"],
+                       "code" => ["application-token", "code"],
+                       "access_token" => ["application-token", "access_token"],
+                       "created_at" => ["application-token", "created_at"],
+                       "scopes" => ["application-token", "scopes"],
+                       "read" => ["application-token", "read"],
+                       "write" => ["application-token", "write"],
+                       "follow" => ["application-token", "follow"],
+               ],
+               "query" => "FROM `application-token` INNER JOIN `application` ON `application-token`.`application-id` = `application`.`id`"
+       ],
        "post-user-view" => [
                "fields" => [
                        "id" => ["post-user", "id"],
index edb0ff63ec16738aacfb4a0c0d6a373530845576..955b5754dcb7e087e68db25a13b11fc7d9e87e52 100644 (file)
@@ -1,32 +1,25 @@
-
-<h1>{{$title}}</h1>
-
-
-<form action="settings/oauth" method="post" autocomplete="off">
-<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
-       <div id="profile-edit-links">
-               <ul>
-                       <li>
-                               <a id="profile-edit-view-link" href="{{$baseurl}}/settings/oauth/add">{{$add}}</a>
-                       </li>
-               </ul>
-       </div>
-
-       {{foreach $apps as $app}}
-       <div class='oauthapp'>
-               <img src='{{$app.icon}}' class="{{if $app.icon}} {{else}}noicon{{/if}}">
-               {{if $app.name}}<h4>{{$app.name}}</h4>{{else}}<h4>{{$noname}}</h4>{{/if}}
-               {{if $app.my}}
-                       {{if $app.oauth_token}}
-                       <div class="settings-submit-wrapper" ><button class="settings-submit"  type="submit" name="remove" value="{{$app.oauth_token}}">{{$remove}}</button></div>
-                       {{/if}}
-               {{/if}}
-               {{if $app.my}}
-               <a href="{{$baseurl}}/settings/oauth/edit/{{$app.client_id}}" class="icon s22 edit" title="{{$edit}}">&nbsp;</a>
-               <a href="{{$baseurl}}/settings/oauth/delete/{{$app.client_id}}?t={{$form_security_token}}" class="icon s22 delete" title="{{$delete}}">&nbsp;</a>
-               {{/if}}         
-       </div>
-       {{/foreach}}
-
-</form>
+<div class="generic-page-wrapper">
+       <h1>{{$title}}</h1>
+       <form action="settings/oauth" method="post" autocomplete="off">
+               <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
+               <table id='application-block' class='table table-condensed table-striped'>
+                       <thead>
+                               <tr>
+                                       <th>{{$name}}</th>
+                                       <th>{{$website}}</th>
+                                       <th>{{$created_at}}</th>
+                               </tr>
+                       </thead>
+                       <tbody>
+                               {{foreach $apps as $app}}
+                               <tr>
+                                       <td>{{$app.name}}</td>
+                                       <td>{{$app.website}}</td>
+                                       <td>{{$app.created_at}}</td>
+                                       <td><a href="{{$baseurl}}/settings/oauth/delete/{{$app.id}}?t={{$form_security_token}}" class="icon s22 delete" title="{{$delete}}">&nbsp;</a></td>
+                               </tr>
+                               {{/foreach}}
+                       </tbody>
+               </table>
+       </form>
+</div>
index c6103cbc82a1749adf93585a322dca89c85ba4ac..98cb96a3f8a9dd8e7b6b5ce1f015de434eb50232 100644 (file)
@@ -1,44 +1,26 @@
 <div class="generic-page-wrapper">
        {{* include the title template for the settings title *}}
-       {{include file="section_title.tpl" title=$title }}
-
-
+       {{include file="section_title.tpl" title=$title}}
        <form action="settings/oauth" method="post" autocomplete="off">
                <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
-               <div id="profile-edit-links">
-                       <ul>
-                               {{*
-                               I commented this out. Initially I wanted to to load the oauth/add into a modal dialog but settings.php
-                               does need $a->argv[2] === 'add' to work and argv[2] isn't available if you load a modal
-                               I leave it at this place as reminder that we need an other solution in settings.php 
-
-                               <li role="menuitem">
-                                       <a id="profile-edit-view-link" onclick="addToModal('{{$baseurl}}/settings/oauth/add')">{{$add}}</a>
-                               </li>
-                               *}}
-
-                               <li role="menuitem">
-                                       <a id="profile-edit-view-link" href="{{$baseurl}}/settings/oauth/add">{{$add}}</a>
-                               </li>
-                       </ul>
-               </div>
-
-               {{foreach $apps as $app}}
-               <div class='oauthapp'>
-                       <img src='{{$app.icon}}' class="{{if $app.icon}} {{else}}noicon{{/if}}">
-                       {{if $app.name}}<h4>{{$app.name}}</h4>{{else}}<h4>{{$noname}}</h4>{{/if}}
-                       {{if $app.my}}
-                               {{if $app.oauth_token}}
-                               <div class="settings-submit-wrapper" ><button class="settings-submit"  type="submit" name="remove" value="{{$app.oauth_token}}">{{$remove}}</button></div>
-                               {{/if}}
-                       {{/if}}
-                       {{if $app.my}}
-                       <a href="{{$baseurl}}/settings/oauth/edit/{{$app.client_id}}" class="btn" title="{{$edit}}"><i class="fa fa-pencil-square-o" aria-hidden="true"></i>&nbsp;</a>
-                       <a href="{{$baseurl}}/settings/oauth/delete/{{$app.client_id}}?t={{$form_security_token}}" class="btn" title="{{$delete}}"><i class="fa fa-trash" aria-hidden="true"></i></a>
-                       {{/if}}
-               </div>
-               {{/foreach}}
-
+               <table id='application-block' class='table table-condensed table-striped'>
+                       <thead>
+                               <tr>
+                                       <th>{{$name}}</th>
+                                       <th>{{$website}}</th>
+                                       <th>{{$created_at}}</th>
+                               </tr>
+                       </thead>
+                       <tbody>
+                               {{foreach $apps as $app}}
+                               <tr>
+                                       <td>{{$app.name}}</td>
+                                       <td>{{$app.website}}</td>
+                                       <td>{{$app.created_at}}</td>
+                                       <td><a href="{{$baseurl}}/settings/oauth/delete/{{$app.id}}?t={{$form_security_token}}" class="btn" title="{{$delete}}"><i class="fa fa-trash" aria-hidden="true"></i></a></td>
+                               </tr>
+                               {{/foreach}}
+                       </tbody>
+               </table>
        </form>
 </div>