Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 3a3a66c

Browse files
committed
Adds linking api
1 parent 8e5ccac commit 3a3a66c

File tree

14 files changed

+272
-0
lines changed

14 files changed

+272
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_data/
2+
_releases/

Api/Controller/Linking.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace YogstationPermissions\Api\Controller;
4+
5+
use XF\Api\Controller\AbstractController;
6+
use XF\Mvc\ParameterBag;
7+
8+
/**
9+
* @api-group Linking
10+
*/
11+
class Linking extends AbstractController
12+
{
13+
/**
14+
* @api-desc Generates a new linking key for a external account.
15+
*
16+
* @api-in <req> str $account_type The type of account (Byond or Discord)
17+
* @api-in <req> str $account_id The external ID of the account being linked
18+
* @api-in str $limit_ip The IP that should be considered to be making the request. If provided, this will be used to prevent brute force attempts.
19+
*
20+
* @api-out str $key the linking key generated.
21+
* @api-out str $url the url the end user needs to access to link.
22+
*/
23+
public function actionPost(ParameterBag $params)
24+
{
25+
$this->assertSuperUserKey();
26+
$this->assertApiScope('linking');
27+
28+
$key = $this->service('YogstationPermissions:Linking\Generate', $params->account_type, $params->account_type)->generateKey();
29+
30+
return $this->apiSuccess([
31+
'key' => $key,
32+
'url' => \XF::app()->router('public')->buildLink('canonical:linking/link', $key, ["key" => $key]),
33+
]);
34+
}
35+
36+
public function actionGet(ParameterBag $params)
37+
{
38+
$this->assertSuperUserKey();
39+
$this->assertApiScope('linking');
40+
41+
$finder = \XF::finder('YogstationPermissions:LinkedAccount');
42+
43+
$user = $finder->where('account_id', $params->account_type)
44+
->where('account_type', $params->account_type)
45+
->with('User')->fetchOne();
46+
47+
if(!$user)
48+
{
49+
return $this->error(\XF::phrase('yg_no_linked_account'));
50+
}
51+
52+
return $this->apiSuccess([
53+
'user' => $user
54+
]);
55+
}
56+
}

Entity/LinkedAccount.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace YogstationPermissions\Entity;
4+
5+
use XF\Mvc\Entity\Entity;
6+
use XF\Mvc\Entity\Structure;
7+
8+
class LinkedAccount extends Entity
9+
{
10+
public static function getStructure(Structure $structure)
11+
{
12+
$structure->table = 'yg_linked_account';
13+
$structure->shortName = 'YG:LinkedAccount';
14+
$structure->primaryKey = 'user_id';
15+
$structure->columns = [
16+
'user_id' => ['type' => self::UINT],
17+
'account_type' => ['type' => self::STR, 'maxLength' => 50],
18+
'account_id' => ['type' => self::STR, 'maxLength' => 255]
19+
];
20+
$structure->relations = [
21+
'User' => [
22+
'entity' => 'XF:User',
23+
'type' => self::TO_ONE,
24+
'conditions' => 'user_id',
25+
'primary' => true
26+
]
27+
];
28+
29+
return $structure;
30+
}
31+
}

Entity/LinkingKey.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace YogstationPermissions\Entity;
4+
5+
use XF\Mvc\Entity\Entity;
6+
use XF\Mvc\Entity\Structure;
7+
8+
class LinkingKey extends Entity
9+
{
10+
public static function getStructure(Structure $structure)
11+
{
12+
$structure->table = 'yg_linking_key';
13+
$structure->shortName = 'YG:LinkingKey';
14+
$structure->primaryKey = 'linking_key';
15+
$structure->columns = [
16+
'linking_key' => ['type' => self::STR, 'maxLength' => 255],
17+
'account_type' => ['type' => self::STR, 'maxLength' => 50],
18+
'account_id' => ['type' => self::STR, 'maxLength' => 255],
19+
'expires' => ['type' => self::UINT]
20+
];
21+
22+
return $structure;
23+
}
24+
}

Pub/Controller/Linking.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace YogstationPermissions\Pub\Controller;
4+
5+
use XF\Pub\Controller\AbstractController;
6+
use XF\Mvc\ParameterBag;
7+
8+
class Linking extends AbstractController {
9+
protected function preDispatchController($action, ParameterBag $params)
10+
{
11+
$this->assertRegistrationRequired();
12+
}
13+
14+
public function actionLink(ParameterBag $params) {
15+
$visitor = \XF::visitor();
16+
17+
$linking_key = \XF::finder('YogstationPermissions:LinkingKey')
18+
->where('linking_key', $params->key)
19+
->fetchOne();
20+
21+
if(!$linking_key) {
22+
return $this->error(\XF::phrase('yg_key_not_exist'));
23+
}
24+
25+
$this->service('YogstationPermissions:Linking\Linking', $visitor->user_id, $linking_key)->link();
26+
27+
return $this->redirect($this->buildLink('linking/success'));
28+
}
29+
30+
public function actionSuccess() {
31+
return $this->view('YogstationPermissions:Linking\Success', 'yg_linking_success');
32+
}
33+
}

Service/Linking/Generate.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace YogstationPermissions\Service\Linking;
4+
5+
class Generate extends \XF\Service\AbstractService
6+
{
7+
8+
protected $account_type;
9+
protected $account_id;
10+
11+
public function __construct(\XF\App $app, $account_type, $account_id)
12+
{
13+
parent::__construct($app);
14+
$this->account_type = $account_type;
15+
$this->account_id = $account_id;
16+
}
17+
18+
public function generateKey()
19+
{
20+
$key = \XF::generateRandomString(255);
21+
22+
$linking_key = $this->em()->create('YogstationPermissions:LinkingKey');
23+
$linking_key->linking_key = $key;
24+
$linking_key->account_type = $this->account_type;
25+
$linking_key->account_id = $this->account_id;
26+
$linking_key->expires = \XF::$time + 60 * 15;
27+
28+
$linking_key->save();
29+
30+
return $key;
31+
}
32+
}

Service/Linking/Linking.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace YogstationPermissions\Service\Linking;
4+
5+
class Linking extends \XF\Service\AbstractService
6+
{
7+
8+
protected $user_id;
9+
protected $linking_key;
10+
11+
public function __construct(\XF\App $app, $user_id, $linking_key)
12+
{
13+
parent::__construct($app);
14+
$this->user_id = $user_id;
15+
$this->linking_key = $linking_key;
16+
}
17+
18+
public function link()
19+
{
20+
$this->removeOldAccounts();
21+
22+
$linked_account = $this->em()->create('YogstationPermissions:LinkedAccount');
23+
$linked_account->user_id = $this->user_id;
24+
$linked_account->account_type = $this->linking_key->account_type;
25+
$linked_account->account_id = $this->linking_key->account_id;
26+
27+
$linked_account->save();
28+
29+
return $key;
30+
}
31+
32+
public function removeOldAccounts() {
33+
$finder = \XF::finder('YogstationPermissions:LinkedAccount');
34+
35+
$linked_account = $finder->where('account_id', $params->account_type)
36+
->where('account_type', $params->account_type)
37+
->fetchOne();
38+
39+
if($user) {
40+
$linked_account->delete();
41+
}
42+
}
43+
}

Setup.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,24 @@ class Setup extends AbstractSetup
1616
use StepRunnerInstallTrait;
1717
use StepRunnerUpgradeTrait;
1818
use StepRunnerUninstallTrait;
19+
20+
public function installStep1()
21+
{
22+
$this->schemaManager()->createTable('yg_linked_account', function(\XF\Db\Schema\Create $table)
23+
{
24+
$table->addColumn('user_id', 'int');
25+
$table->addColumn('account_type', 'varchar', 64);
26+
$table->addColumn('account_id', 'varchar', 255);
27+
$table->addPrimaryKey('user_id');
28+
});
29+
30+
$this->schemaManager()->createTable('yg_linking_key', function(\XF\Db\Schema\Create $table)
31+
{
32+
$table->addColumn('linking_key', 'varchar', 255);
33+
$table->addColumn('account_type', 'varchar', 64);
34+
$table->addColumn('account_id', 'varchar', 255);
35+
$table->addColumn('expires', 'int');
36+
$table->addPrimaryKey('linking_key');
37+
});
38+
}
1939
}

_output/api_scopes/_metadata.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"linking.json": {
3+
"hash": "5620c528fb9d686395a806aff70c7b60"
4+
}
5+
}

_output/api_scopes/linking.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"api_scope_id": "linking"
3+
}

0 commit comments

Comments
 (0)