. // }}} /** * ActivityPub implementation for GNU social * * @package GNUsocial * @category API * * @author Diogo Peralta Cordeiro * @author Hugo Sales * @copyright 2022 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ namespace Plugin\OAuth2; use App\Core\Event; use App\Core\Modules\Plugin; use App\Core\Router; use App\Util\Common; use DateInterval; use EventResult; use Exception; use League\OAuth2\Server\AuthorizationServer; use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Grant\AuthCodeGrant; use Plugin\OAuth2\Controller as C; use Plugin\OAuth2\Util\ExpandedBearerTokenResponse; use XML_XRD_Element_Link; /** * Adds OAuth2 support to GNU social when enabled * * @copyright 2022 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class OAuth2 extends Plugin { public const OAUTH_REQUEST_TOKEN_REL = 'http://apinamespace.org/oauth/request_token'; public const OAUTH_ACCESS_TOKEN_REL = 'http://apinamespace.org/oauth/access_token'; public const OAUTH_AUTHORIZE_REL = 'http://apinamespace.org/oauth/authorize'; public static ?AuthorizationServer $authorization_server = null; public static function version(): string { return '3.0.0'; } /** * @throws Exception */ public function onInitializePlugin(): EventResult { self::$authorization_server = new AuthorizationServer( new Repository\Client, new Repository\AccessToken, new Repository\Scope, privateKey: new CryptKey(keyPath: Common::config('oauth2', 'private_key'), passPhrase: Common::config('oauth2', 'private_key_password')), encryptionKey: Common::config('oauth2', 'encryption_key'), responseType: new ExpandedBearerTokenResponse(), ); self::$authorization_server->enableGrantType( new AuthCodeGrant( new Repository\AuthCode, new Repository\RefreshToken, new DateInterval('PT10M'), // ??? ), new DateInterval('PT1H'), ); return Event::next; } /** * This code executes when GNU social creates the page routing, and we hook * on this event to add our Inbox and Outbox handler for ActivityPub. * * @param Router $r the router that was initialized */ public function onAddRoute(Router $r): EventResult { $r->connect('oauth2_mastodon_api_apps', '/api/v1/apps', C\Client::class, ['http-methods' => ['POST']]); $r->connect('oauth2_client', '/oauth/client', C\Client::class, ['http-methods' => ['POST']]); $r->connect('oauth2_authorize', '/oauth/authorize', C\Authorize::class); $r->connect('oauth2_token', '/oauth/token', C\Token::class); return Event::next; } public function onEndHostMetaLinks(array &$links): EventResult { $links[] = new XML_XRD_Element_Link(self::OAUTH_REQUEST_TOKEN_REL, Router::url('oauth2_client', type: Router::ABSOLUTE_URL)); $links[] = new XML_XRD_Element_Link(self::OAUTH_AUTHORIZE_REL, Router::url('oauth2_authorize', type: Router::ABSOLUTE_URL)); $links[] = new XML_XRD_Element_Link(self::OAUTH_ACCESS_TOKEN_REL, Router::url('oauth2_token', type: Router::ABSOLUTE_URL)); return Event::next; } }