Skip to content

Commit 98b3355

Browse files
committed
very basic initial push of API
1 parent c080025 commit 98b3355

File tree

13 files changed

+555
-118
lines changed

13 files changed

+555
-118
lines changed

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
APP_ENV=local
22
APP_DEBUG=true
33
APP_KEY=SomeRandomString
4+
JWT_SECRET=ChangeMe
45

56
DB_HOST=localhost
67
DB_PORT=3306
@@ -22,3 +23,7 @@ MAIL_PORT=2525
2223
MAIL_USERNAME=null
2324
MAIL_PASSWORD=null
2425
MAIL_ENCRYPTION=null
26+
27+
API_PREFIX=api
28+
API_VERSION=v1
29+
API_DEBUG=false

app/Exceptions/Handler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function render($request, Exception $e)
5555
$e = new NotFoundHttpException($e->getMessage(), $e);
5656
}
5757

58-
if ($request->isXmlHttpRequest() || $request->ajax() || $request->is('api/*') || $request->is('remote/*')) {
58+
if ($request->isXmlHttpRequest() || $request->ajax() || $request->is('remote/*')) {
5959

6060
$exception = 'An exception occured while attempting to perform this action, please try again.';
6161

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\API;
4+
5+
use JWTAuth;
6+
use Tymon\JWTAuth\Exceptions\JWTException;
7+
8+
use Illuminate\Http\Request;
9+
use \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
10+
use \Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
11+
12+
use Pterodactyl\Transformers\UserTransformer;
13+
use Pterodactyl\Models;
14+
15+
/**
16+
* @Resource("Auth", uri="/auth")
17+
*/
18+
class AuthController extends BaseController
19+
{
20+
21+
/**
22+
* Authenticate
23+
*
24+
* Authenticate with the API to recieved a JSON Web Token
25+
*
26+
* @Post("/login")
27+
* @Versions({"v1"})
28+
* @Request({"email": "e@mail.com", "password": "soopersecret"})
29+
* @Response(200, body={"token": "<jwt-token>"})
30+
*/
31+
public function postLogin(Request $request) {
32+
$credentials = $request->only('email', 'password');
33+
34+
try {
35+
$token = JWTAuth::attempt($credentials, [
36+
'permissions' => [
37+
'view_users' => true,
38+
'edit_users' => true,
39+
'delete_users' => false,
40+
]
41+
]);
42+
if (!$token) {
43+
throw new UnauthorizedHttpException('');
44+
}
45+
} catch (JWTException $ex) {
46+
throw new ServiceUnavailableHttpException('');
47+
}
48+
49+
return compact('token');
50+
}
51+
52+
/**
53+
* Check if Authenticated
54+
*
55+
* @Post("/validate")
56+
* @Versions({"v1"})
57+
* @Request(headers={"Authorization": "Bearer <jwt-token>"})
58+
* @Response(204);
59+
*/
60+
public function postValidate(Request $request) {
61+
return $this->response->noContent();
62+
}
63+
64+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\API;
4+
5+
use Dingo\Api\Routing\Helpers;
6+
use Illuminate\Routing\Controller;
7+
8+
class BaseController extends Controller
9+
{
10+
use Helpers;
11+
}

app/Http/Controllers/API/UserController.php

Lines changed: 18 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,32 @@
22

33
namespace Pterodactyl\Http\Controllers\API;
44

5-
use Gate;
6-
use Log;
7-
use Debugbar;
8-
use Pterodactyl\Models\API;
9-
use Pterodactyl\Models\User;
10-
11-
use Pterodactyl\Http\Controllers\Controller;
125
use Illuminate\Http\Request;
136

14-
class UserController extends Controller
15-
{
16-
17-
/**
18-
* Constructor
19-
*/
20-
public function __construct()
21-
{
22-
//
23-
}
24-
25-
public function getAllUsers(Request $request)
26-
{
27-
28-
// Policies don't work if the user isn't logged in for whatever reason in Laravel...
29-
if(!API::checkPermission($request->header('X-Authorization'), 'get-users')) {
30-
return API::noPermissionError();
31-
}
7+
use Pterodactyl\Transformers\UserTransformer;
8+
use Pterodactyl\Models;
329

33-
return response()->json([
34-
'users' => User::all()
35-
]);
36-
}
10+
/**
11+
* @Resource("Users", uri="/users")
12+
*/
13+
class UserController extends BaseController
14+
{
3715

3816
/**
39-
* Returns JSON response about a user given their ID.
40-
* If fields are provided only those fields are returned.
17+
* List All Users
4118
*
42-
* Does not return protected fields (i.e. password & totp_secret)
19+
* Lists all users currently on the system.
4320
*
44-
* @param Request $request
45-
* @param int $id
46-
* @param string $fields
47-
* @return Response
21+
* @Get("/{?page}")
22+
* @Versions({"v1"})
23+
* @Parameters({
24+
* @Parameter("page", type="integer", description="The page of results to view.", default=1)
25+
* })
26+
* @Response(200)
4827
*/
49-
public function getUser(Request $request, $id, $fields = null)
50-
{
51-
52-
// Policies don't work if the user isn't logged in for whatever reason in Laravel...
53-
if(!API::checkPermission($request->header('X-Authorization'), 'get-users')) {
54-
return API::noPermissionError();
55-
}
56-
57-
if (is_null($fields)) {
58-
return response()->json(User::find($id));
59-
}
60-
61-
$query = User::where('id', $id);
62-
$explode = explode(',', $fields);
63-
64-
foreach($explode as &$exploded) {
65-
if(!empty($exploded)) {
66-
$query->addSelect($exploded);
67-
}
68-
}
69-
70-
try {
71-
return response()->json($query->get());
72-
} catch (\Exception $e) {
73-
if ($e instanceof \Illuminate\Database\QueryException) {
74-
return response()->json([
75-
'error' => 'One of the fields provided in your argument list is invalid.'
76-
], 500);
77-
}
78-
throw $e;
79-
}
80-
28+
public function getUsers(Request $request) {
29+
$users = Models\User::paginate(15);
30+
return $this->response->paginator($users, new UserTransformer);
8131
}
8232

8333
}

app/Http/Kernel.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class Kernel extends HttpKernel
1717
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
1818
\Illuminate\Session\Middleware\StartSession::class,
1919
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
20-
\Pterodactyl\Http\Middleware\VerifyCsrfToken::class,
2120
];
2221

2322
/**
@@ -30,7 +29,7 @@ class Kernel extends HttpKernel
3029
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
3130
'guest' => \Pterodactyl\Http\Middleware\RedirectIfAuthenticated::class,
3231
'server' => \Pterodactyl\Http\Middleware\CheckServer::class,
33-
'api' => \Pterodactyl\Http\Middleware\APIAuthenticate::class,
3432
'admin' => \Pterodactyl\Http\Middleware\AdminAuthenticate::class,
33+
'csrf' => \Pterodactyl\Http\Middleware\VerifyCsrfToken::class,
3534
];
3635
}

app/Http/Middleware/APIAuthenticate.php

Lines changed: 0 additions & 46 deletions
This file was deleted.

app/Http/Routes/APIRoutes.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Routes;
4+
5+
use Pterodactyl\Models;
6+
use Illuminate\Routing\Router;
7+
8+
class APIRoutes
9+
{
10+
11+
public function map(Router $router) {
12+
13+
app('Dingo\Api\Auth\Auth')->extend('jwt', function ($app) {
14+
return new \Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']);
15+
});
16+
17+
$api = app('Dingo\Api\Routing\Router');
18+
19+
$api->version('v1', function ($api) {
20+
$api->post('auth/login', [
21+
'as' => 'api.auth.login',
22+
'uses' => 'Pterodactyl\Http\Controllers\API\AuthController@postLogin'
23+
]);
24+
25+
$api->post('auth/validate', [
26+
'middleware' => 'api.auth',
27+
'as' => 'api.auth.validate',
28+
'uses' => 'Pterodactyl\Http\Controllers\API\AuthController@postValidate'
29+
]);
30+
});
31+
32+
$api->version('v1', ['middleware' => 'api.auth'], function ($api) {
33+
34+
$api->get('users', [
35+
'as' => 'api.auth.validate',
36+
'uses' => 'Pterodactyl\Http\Controllers\API\UserController@getUsers'
37+
]);
38+
39+
$api->get('users/{id}', function($id) {
40+
return Models\User::findOrFail($id);
41+
});
42+
43+
44+
});
45+
}
46+
47+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Pterodactyl\Transformers;
4+
5+
use Pterodactyl\Models\User;
6+
use League\Fractal\TransformerAbstract;
7+
8+
class UserTransformer extends TransformerAbstract
9+
{
10+
11+
/**
12+
* Turn this item object into a generic array
13+
*
14+
* @return array
15+
*/
16+
public function transform(User $user)
17+
{
18+
return $user;
19+
}
20+
21+
}

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
"php": ">=5.5.9",
99
"laravel/framework": "5.2.*",
1010
"barryvdh/laravel-debugbar": "^2.0",
11+
"dingo/api": "1.0.*@dev",
1112
"doctrine/dbal": "^2.5",
1213
"guzzlehttp/guzzle": "^6.1",
1314
"pragmarx/google2fa": "^0.7.1",
1415
"webpatser/laravel-uuid": "^2.0",
1516
"prologue/alerts": "^0.4.0",
16-
"s1lentium/iptools": "^1.0"
17+
"s1lentium/iptools": "^1.0",
18+
"tymon/jwt-auth": "^0.5.6"
1719
},
1820
"require-dev": {
1921
"fzaninotto/faker": "~1.4",

0 commit comments

Comments
 (0)