forked from deblan/gist
Merge stash
This commit is contained in:
parent
a9435906fe
commit
80b3c0bbdb
|
@ -6,6 +6,7 @@ security:
|
|||
login_required_to_view_gist: false
|
||||
login_required_to_view_embeded_gist: false
|
||||
api:
|
||||
enabled: true
|
||||
base_url: 'https://gist.deblan.org/'
|
||||
data:
|
||||
path: data/git
|
||||
|
|
|
@ -57,10 +57,14 @@ revisions:
|
|||
path: /revs/{gist}
|
||||
defaults: {_controller: Gist\Controller\ViewController::revisionsAction, _locale: en}
|
||||
|
||||
api_list:
|
||||
path: /api/list/{apiKey}
|
||||
defaults: {_controller: Gist\Controller\ApiController::listAction, _locale: en}
|
||||
|
||||
api_create:
|
||||
path: /api/create
|
||||
path: /api/create/{apiKey}
|
||||
defaults: {_controller: Gist\Controller\ApiController::createAction, _locale: en}
|
||||
|
||||
api_update:
|
||||
path: /api/update/{gist}
|
||||
path: /api/update/{gist}/{apiKey}
|
||||
defaults: {_controller: Gist\Controller\ApiController::updateAction, _locale: en}
|
||||
|
|
|
@ -12,25 +12,26 @@ use GuzzleHttp\Client as BaseClient;
|
|||
class Client extends BaseClient
|
||||
{
|
||||
/**
|
||||
* URI of creation
|
||||
* URI of creation.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const CREATE = '/en/api/create';
|
||||
|
||||
/**
|
||||
* URI of update
|
||||
* URI of update.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const UPDATE = '/en/api/update/{gist}';
|
||||
|
||||
/**
|
||||
* Creates a gist
|
||||
* Creates a gist.
|
||||
*
|
||||
* @param string $title The title
|
||||
* @param string $type The type
|
||||
* @param string $content The content
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function create($title, $type, $content)
|
||||
|
|
|
@ -8,6 +8,8 @@ use Symfony\Component\HttpFoundation\JsonResponse;
|
|||
use Gist\Form\ApiCreateGistForm;
|
||||
use Gist\Model\GistQuery;
|
||||
use Gist\Form\ApiUpdateGistForm;
|
||||
use GitWrapper\GitException;
|
||||
use Gist\Model\UserQuery;
|
||||
|
||||
/**
|
||||
* Class ApiController.
|
||||
|
@ -17,16 +19,73 @@ use Gist\Form\ApiUpdateGistForm;
|
|||
class ApiController extends Controller
|
||||
{
|
||||
/**
|
||||
* Creates a gist.
|
||||
* Lists gists.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $apiKey
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function createAction(Request $request)
|
||||
public function listAction(Request $request, $apiKey)
|
||||
{
|
||||
$app = $this->getApp();
|
||||
|
||||
if (false === $app['settings']['api']['enabled']) {
|
||||
return new Response('', 403);
|
||||
}
|
||||
|
||||
if (false === $this->isValidApiKey($apiKey)) {
|
||||
return $this->invalidApiKeyResponse();
|
||||
}
|
||||
|
||||
if (false === $request->isMethod('get')) {
|
||||
return $this->invalidMethodResponse('GET method is required.');
|
||||
}
|
||||
|
||||
$gists = GistQuery::create()->find();
|
||||
$data = array();
|
||||
|
||||
foreach ($gists as $gist) {
|
||||
try {
|
||||
$history = $app['gist']->getHistory($gist);
|
||||
|
||||
$value = $gist->toArray();
|
||||
$value['url'] = $request->getSchemeAndHttpHost().$app['url_generator']->generate(
|
||||
'view',
|
||||
array(
|
||||
'gist' => $gist->getFile(),
|
||||
'commit' => array_pop($history)['commit'],
|
||||
)
|
||||
);
|
||||
|
||||
$data[] = $value;
|
||||
} catch (GitException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return new JsonResponse($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a gist.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $apiKey
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function createAction(Request $request, $apiKey)
|
||||
{
|
||||
$app = $this->getApp();
|
||||
|
||||
if (false === $app['settings']['api']['enabled']) {
|
||||
return new Response('', 403);
|
||||
}
|
||||
|
||||
if (false === $this->isValidApiKey($apiKey)) {
|
||||
return $this->invalidApiKeyResponse();
|
||||
}
|
||||
|
||||
if (false === $request->isMethod('post')) {
|
||||
return $this->invalidMethodResponse('POST method is required.');
|
||||
}
|
||||
|
@ -48,16 +107,16 @@ class ApiController extends Controller
|
|||
|
||||
$history = $app['gist']->getHistory($gist);
|
||||
|
||||
return new JsonResponse(array(
|
||||
'url' => $request->getSchemeAndHttpHost().$app['url_generator']->generate(
|
||||
$data = $gist->toArray();
|
||||
$data['url'] = $request->getSchemeAndHttpHost().$app['url_generator']->generate(
|
||||
'view',
|
||||
array(
|
||||
'gist' => $gist->getFile(),
|
||||
'commit' => array_pop($history)['commit'],
|
||||
)
|
||||
),
|
||||
'gist' => $gist->toArray(),
|
||||
));
|
||||
);
|
||||
|
||||
return new JsonResponse($data);
|
||||
}
|
||||
|
||||
return $this->invalidRequestResponse('Invalid field(s)');
|
||||
|
@ -68,13 +127,22 @@ class ApiController extends Controller
|
|||
*
|
||||
* @param Request $request
|
||||
* @param string $gist
|
||||
* @param string $apiKey
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function updateAction(Request $request, $gist)
|
||||
public function updateAction(Request $request, $gist, $apiKey)
|
||||
{
|
||||
$app = $this->getApp();
|
||||
|
||||
if (false === $app['settings']['api']['enabled']) {
|
||||
return new Response('', 403);
|
||||
}
|
||||
|
||||
if (false === $this->isValidApiKey($apiKey)) {
|
||||
return $this->invalidApiKeyResponse();
|
||||
}
|
||||
|
||||
if (false === $request->isMethod('post')) {
|
||||
return $this->invalidMethodResponse('POST method is required.');
|
||||
}
|
||||
|
@ -106,21 +174,38 @@ class ApiController extends Controller
|
|||
|
||||
$history = $app['gist']->getHistory($gist);
|
||||
|
||||
return new JsonResponse(array(
|
||||
'url' => $request->getSchemeAndHttpHost().$app['url_generator']->generate(
|
||||
$data = $gist->toArray();
|
||||
$data['url'] = $request->getSchemeAndHttpHost().$app['url_generator']->generate(
|
||||
'view',
|
||||
array(
|
||||
'gist' => $gist->getFile(),
|
||||
'commit' => array_pop($history)['commit'],
|
||||
)
|
||||
),
|
||||
'gist' => $gist->toArray(),
|
||||
));
|
||||
);
|
||||
|
||||
return new JsonResponse($data);
|
||||
}
|
||||
|
||||
return $this->invalidRequestResponse('Invalid field(s)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an invalid api key response.
|
||||
*
|
||||
* @param mixed $message
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
protected function invalidApiKeyResponse()
|
||||
{
|
||||
$data = [
|
||||
'error' => ' Unauthorized',
|
||||
'message' => 'Invalid API KEY',
|
||||
];
|
||||
|
||||
return new JsonResponse($data, 401);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an invalid method response.
|
||||
*
|
||||
|
@ -154,4 +239,11 @@ class ApiController extends Controller
|
|||
|
||||
return new JsonResponse($data, 400);
|
||||
}
|
||||
|
||||
protected function isValidApiKey($apiKey)
|
||||
{
|
||||
return !empty($apiKey) && UserQuery::create()
|
||||
->filterByApiKey($apiKey)
|
||||
->count() === 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class LoginController extends Controller
|
|||
{
|
||||
$app = $this->getApp();
|
||||
|
||||
if (false === $app['settings']['enable_registration']) {
|
||||
if (false === $app['settings']['security']['enable_registration']) {
|
||||
return new Response('', 403);
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ class LoginController extends Controller
|
|||
{
|
||||
$app = $this->getApp();
|
||||
|
||||
if (false === $app['settings']['enable_login']) {
|
||||
if (false === $app['settings']['security']['enable_login']) {
|
||||
return new Response('', 403);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,24 @@ class MyController extends Controller
|
|||
|
||||
$gists = $this->getUser()->getGistsPager($page, $options);
|
||||
|
||||
$apiKey = $this->getUser()->getApiKey();
|
||||
|
||||
if (empty($apiKey)) {
|
||||
$regenerateApiKey = true;
|
||||
} elseif ($request->request->get('apiKey') === $apiKey && $request->request->has('generateApiKey')) {
|
||||
$regenerateApiKey = true;
|
||||
} else {
|
||||
$regenerateApiKey = false;
|
||||
}
|
||||
|
||||
if ($regenerateApiKey) {
|
||||
$apiKey = $app['salt_generator']->generate(32, true);
|
||||
|
||||
$this->getUser()
|
||||
->setApiKey($apiKey)
|
||||
->save();
|
||||
}
|
||||
|
||||
if ($request->isMethod('post')) {
|
||||
$deleteForm->handleRequest($request);
|
||||
$passwordForm->handleRequest($request);
|
||||
|
@ -104,6 +122,7 @@ class MyController extends Controller
|
|||
array(
|
||||
'gists' => $gists,
|
||||
'page' => $page,
|
||||
'apiKey' => $apiKey,
|
||||
'deleteForm' => $deleteForm->createView(),
|
||||
'filterForm' => $filterForm->createView(),
|
||||
'passwordForm' => $passwordForm->createView(),
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Gist\Model;
|
||||
|
||||
use Gist\Model\Base\Gist as BaseGist;
|
||||
use Propel\Runtime\Map\TableMap;
|
||||
|
||||
/**
|
||||
* Class Gist.
|
||||
|
@ -86,4 +87,25 @@ class Gist extends BaseGist
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false)
|
||||
{
|
||||
$data = parent::toArray(
|
||||
$keyType,
|
||||
$includeLazyLoadColumns,
|
||||
$alreadyDumpedObjects,
|
||||
$includeForeignObjects
|
||||
);
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
$newKey = lcfirst($key);
|
||||
unset($data[$key]);
|
||||
$data[$newKey] = $value;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<column name="password" type="VARCHAR" size="255" required="true" />
|
||||
<column name="roles" type="VARCHAR" size="255" required="true" />
|
||||
<column name="salt" type="VARCHAR" size="64" required="true" />
|
||||
<column name="api_key" type="VARCHAR" size="32" required="true" />
|
||||
|
||||
<behavior name="timestampable"/>
|
||||
</table>
|
||||
|
|
|
@ -230,6 +230,24 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if app.settings.api.enabled %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{ 'api.title'|trans }}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="tab-content">
|
||||
<form action="{{ path('my', params) }}" method="post">
|
||||
<p>
|
||||
<input type="text" name="apiKey" id="form-api-key" size="32" value="{{ apiKey }}" data-key="{{ apiKey }}">
|
||||
<input type="submit" name="generateApiKey" value="{{ 'api.form.generate' }}">
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
{% set theme_settings = app.settings.theme %}
|
||||
{% set security_dettings = app.settings.security %}
|
||||
{% set security_settings = app.settings.security %}
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
{% block css %}
|
||||
|
@ -56,14 +56,14 @@
|
|||
{{ 'app.menu.my.logout.title'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% elseif security_dettings.enable_login %}
|
||||
{% elseif security_settings.enable_login %}
|
||||
<li>
|
||||
<a href="{{ path('login') }}">
|
||||
{{ 'app.menu.my.login.title'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if security_dettings.enable_registration %}
|
||||
{% if security_settings.enable_registration %}
|
||||
<li>
|
||||
<a href="{{ path('register') }}">
|
||||
{{ 'app.menu.my.register.title'|trans }}
|
||||
|
|
|
@ -18,18 +18,30 @@ class SaltGenerator
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate($length = 32)
|
||||
public function generate($length = 32, $isApiKey = false)
|
||||
{
|
||||
if (!is_numeric($length)) {
|
||||
throw new InvalidArgumentException('Paramter length must be a valid integer.');
|
||||
}
|
||||
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
return substr(base64_encode(openssl_random_pseudo_bytes($length)), 0, $length);
|
||||
$string = base64_encode(openssl_random_pseudo_bytes(256));
|
||||
}
|
||||
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
return substr(base64_encode(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)), 0, $length);
|
||||
$string = base64_encode(mcrypt_create_iv(256, MCRYPT_DEV_URANDOM));
|
||||
}
|
||||
|
||||
if (!empty($string)) {
|
||||
if (true === $isApiKey) {
|
||||
$string = str_replace(
|
||||
array('+', '%', '/', '#', '&'),
|
||||
'',
|
||||
$string
|
||||
);
|
||||
}
|
||||
|
||||
return substr($string, 0, $length);
|
||||
}
|
||||
|
||||
throw new RuntimeException('You must enable openssl or mcrypt modules.');
|
||||
|
|
|
@ -126,6 +126,7 @@ class UserProvider implements UserProviderInterface
|
|||
$user
|
||||
->setRoles('ROLE_USER')
|
||||
->setPassword($this->encoder->encodePassword($password, $user->getSalt()))
|
||||
->setApiKey($this->saltGenerator->generate(32, true))
|
||||
->save();
|
||||
|
||||
return $user;
|
||||
|
|
|
@ -98,6 +98,10 @@ var myEvents = function() {
|
|||
$('#form-deletion form').submit();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change keyup keydown', '#form-api-key', function() {
|
||||
$(this).val($(this).data('key'));
|
||||
});
|
||||
}
|
||||
|
||||
var mainEditorEvents = function() {
|
||||
|
|
Loading…
Reference in a new issue