diff --git a/app/bootstrap.php.d/20-routing.php b/app/bootstrap.php.d/20-routing.php index 8635ae6..92d3df5 100644 --- a/app/bootstrap.php.d/20-routing.php +++ b/app/bootstrap.php.d/20-routing.php @@ -1,6 +1,7 @@ extend('routes', function ($routes, $app) { return $routes; }); + +$app['resolver'] = $app->share(function () use ($app) { + if (isset($app['logger'])){ + $logger = $app['logger']; + } else{ + $logger = null; + } + + return new ControllerResolver($app, isset($app['logger']) ? $app['logger'] : null); +}); diff --git a/app/bootstrap.php.d/50-git.php b/app/bootstrap.php.d/50-git.php index 8156823..5508ca5 100644 --- a/app/bootstrap.php.d/50-git.php +++ b/app/bootstrap.php.d/50-git.php @@ -1,7 +1,7 @@ share(function ($app) { }); $app['gist'] = $app->share(function ($app) { - return new GistService($app['gist_path'], $app['git_wrapper'], $app['git_working_copy'], $app['geshi']); + return new Gist($app['gist_path'], $app['git_wrapper'], $app['git_working_copy'], $app['geshi']); }); diff --git a/src/Gist/Controller/ApiController.php b/src/Gist/Controller/ApiController.php index 03a5221..bdaf33c 100644 --- a/src/Gist/Controller/ApiController.php +++ b/src/Gist/Controller/ApiController.php @@ -2,7 +2,6 @@ namespace Gist\Controller; -use Silex\Application; use Symfony\Component\HttpFoundation\Request; use Gist\Model\Gist; use Symfony\Component\HttpFoundation\JsonResponse; @@ -16,8 +15,10 @@ use Gist\Form\ApiUpdateGistForm; */ class ApiController extends Controller { - public function createAction(Request $request, Application $app) + public function createAction(Request $request) { + $app = $this->getApp(); + if (false === $request->isMethod('post')) { return $this->invalidMethodResponse('POST method is required.'); } @@ -53,9 +54,11 @@ class ApiController extends Controller return $this->invalidRequestResponse('Invalid field(s)'); } - - public function updateAction(Request $request, Application $app, $gist) + + public function updateAction(Request $request, $gist) { + $app = $this->getApp(); + if (false === $request->isMethod('post')) { return $this->invalidMethodResponse('POST method is required.'); } diff --git a/src/Gist/Controller/Controller.php b/src/Gist/Controller/Controller.php index 65a2e89..22330f3 100644 --- a/src/Gist/Controller/Controller.php +++ b/src/Gist/Controller/Controller.php @@ -14,8 +14,22 @@ use Symfony\Component\HttpFoundation\Response; */ class Controller { - protected function notFoundResponse(Application $app) + protected $app; + + public function __construct(Application $app) { + $this->app = $app; + } + + public function getApp() + { + return $this->app; + } + + protected function notFoundResponse() + { + $app = $this->getApp(); + return new Response( $app['twig']->render( 'View/notFound.html.twig', @@ -25,8 +39,10 @@ class Controller ); } - protected function getViewOptions(Request $request, Application $app, $gist, $commit) + protected function getViewOptions(Request $request, $gist, $commit) { + $app = $this->getApp(); + $gist = GistQuery::create()->findOneByFile($gist); if (null === $gist) { @@ -39,7 +55,7 @@ class Controller return null; } - $content = $this->getContentByCommit($app, $gist, $commit, $history); + $content = $this->getContentByCommit($gist, $commit, $history); return array( 'gist' => $gist, @@ -51,8 +67,10 @@ class Controller ); } - protected function getContentByCommit(Application $app, Gist $gist, &$commit, $history) + protected function getContentByCommit(Gist $gist, &$commit, $history) { + $app = $this->getApp(); + if ($commit === 0) { $commit = $history[0]['commit']; } else { @@ -72,8 +90,10 @@ class Controller return $app['gist']->getContent($gist, $commit); } - public function getUser(Application $app) + public function getUser() { + $app = $this->getApp(); + $securityContext = $app['security']; $securityToken = $securityContext->getToken(); @@ -84,10 +104,12 @@ class Controller return $securityToken->getUser(); } - public function render($template, array $params, Application $app) + public function render($template, array $params) { + $app = $this->getApp(); + if (!isset($params['user'])) { - $params['user'] = $this->getUser($app); + $params['user'] = $this->getUser(); } return $app['twig']->render( diff --git a/src/Gist/Controller/EditController.php b/src/Gist/Controller/EditController.php index d79b09f..d368ade 100644 --- a/src/Gist/Controller/EditController.php +++ b/src/Gist/Controller/EditController.php @@ -2,7 +2,6 @@ namespace Gist\Controller; -use Silex\Application; use Symfony\Component\HttpFoundation\Request; use Gist\Form\CreateGistForm; use Gist\Form\CloneGistForm; @@ -16,8 +15,10 @@ use Symfony\Component\HttpFoundation\RedirectResponse; */ class EditController extends Controller { - public function createAction(Request $request, Application $app) + public function createAction(Request $request) { + $app = $this->getApp(); + $data = array( 'type' => 'html', 'cipher' => 'no', @@ -30,7 +31,7 @@ class EditController extends Controller $form->submit($request); if ($form->isValid()) { - $gist = $app['gist']->create(new Gist(), $form->getData()); + $gist = $app['gist']->create(new Gist(), $form->getData(), $this->getUser()); } } @@ -39,14 +40,15 @@ class EditController extends Controller array( 'gist' => isset($gist) ? $gist : null, 'form' => $form->createView(), - ), - $app + ) ); } - public function cloneAction(Request $request, Application $app, $gist, $commit) + public function cloneAction(Request $request, $gist, $commit) { - $viewOptions = $this->getViewOptions($request, $app, $gist, $commit); + $app = $this->getApp(); + + $viewOptions = $this->getViewOptions($request, $gist, $commit); $data = array( 'type' => $viewOptions['gist']->getType(), @@ -81,6 +83,6 @@ class EditController extends Controller $viewOptions['form'] = $form->createView(); - return $this->render('Edit/clone.html.twig', $viewOptions, $app); + return $this->render('Edit/clone.html.twig', $viewOptions); } } diff --git a/src/Gist/Controller/LoginController.php b/src/Gist/Controller/LoginController.php index bbaa88f..b7803e1 100644 --- a/src/Gist/Controller/LoginController.php +++ b/src/Gist/Controller/LoginController.php @@ -2,9 +2,7 @@ namespace Gist\Controller; -use Gist\Controller\Controller; use Symfony\Component\HttpFoundation\Request; -use Silex\Application; use Gist\Model\User; use Gist\Form\UserRegisterForm; use Gist\Form\UserLoginForm; @@ -16,8 +14,10 @@ use Symfony\Component\HttpFoundation\Response; */ class LoginController extends Controller { - public function registerAction(Request $request, Application $app) + public function registerAction(Request $request) { + $app = $this->getApp(); + if (false === $app['enable_registration']) { return new Response('', 403); } @@ -55,13 +55,14 @@ class LoginController extends Controller 'form' => $form->createView(), 'error' => isset($error) ? $error : '', 'success' => isset($success) ? $success : '', - ], - $app + ] ); } - - public function loginAction(Request $request, Application $app) + + public function loginAction(Request $request) { + $app = $this->getApp(); + if (false === $app['enable_login']) { return new Response('', 403); } @@ -86,17 +87,15 @@ class LoginController extends Controller [ 'form' => $form->createView(), 'error' => isset($error) ? $error : '', - ], - $app + ] ); } public function loginCheckAction() { } - + public function logoutAction() { } } - diff --git a/src/Gist/Controller/MyController.php b/src/Gist/Controller/MyController.php index 9ef2e11..a343404 100644 --- a/src/Gist/Controller/MyController.php +++ b/src/Gist/Controller/MyController.php @@ -2,9 +2,7 @@ namespace Gist\Controller; -use Gist\Controller\Controller; use Symfony\Component\HttpFoundation\Request; -use Silex\Application; /** * Class MyController @@ -12,10 +10,8 @@ use Silex\Application; */ class MyController extends Controller { - public function myAction(Request $request, Application $app) + public function myAction(Request $request) { - echo '
', var_dump($this->getUser($app)), '
'; - die; + $app = $this->getApp(); } } - diff --git a/src/Gist/Controller/ViewController.php b/src/Gist/Controller/ViewController.php index 6cf8fb7..c4476b5 100644 --- a/src/Gist/Controller/ViewController.php +++ b/src/Gist/Controller/ViewController.php @@ -14,34 +14,38 @@ use Symfony\Component\HttpFoundation\Response; */ class ViewController extends Controller { - public function viewAction(Request $request, Application $app, $gist, $commit) + public function viewAction(Request $request, $gist, $commit) { - $viewOptions = $this->getViewOptions($request, $app, $gist, $commit); + $app = $this->getApp(); + + $viewOptions = $this->getViewOptions($request, $gist, $commit); if (is_array($viewOptions)) { - return $this->render('View/view.html.twig', $viewOptions, $app); + return $this->render('View/view.html.twig', $viewOptions); } else { - return $this->notFoundResponse($app); + return $this->notFoundResponse(); } } - public function embedAction(Request $request, Application $app, $gist, $commit) + public function embedAction(Request $request, $gist, $commit) { - $viewOptions = $this->getViewOptions($request, $app, $gist, $commit); + $app = $this->getApp(); + + $viewOptions = $this->getViewOptions($request, $gist, $commit); if (is_array($viewOptions)) { return $app['twig']->render('View/embed.html.twig', $viewOptions); } else { - return $this->notFoundResponse($app); + return $this->notFoundResponse(); } } - public function embedJsAction(Request $request, Application $app, $gist, $commit) + public function embedJsAction(Request $request, $gist, $commit) { - $viewOptions = $this->getViewOptions($request, $app, $gist, $commit); + $viewOptions = $this->getViewOptions($request, $gist, $commit); return new Response( - $this->render('View/embedJs.html.twig', $viewOptions, $app), + $this->render('View/embedJs.html.twig', $viewOptions), 200, array( 'Content-Type' => 'text/javascript', @@ -49,9 +53,9 @@ class ViewController extends Controller ); } - public function rawAction(Request $request, Application $app, $gist, $commit) + public function rawAction(Request $request, $gist, $commit) { - $viewOptions = $this->getViewOptions($request, $app, $gist, $commit); + $viewOptions = $this->getViewOptions($request, $gist, $commit); if (is_array($viewOptions)) { return new Response( @@ -62,13 +66,15 @@ class ViewController extends Controller ) ); } else { - return $this->notFoundResponse($app); + return $this->notFoundResponse(); } } - public function downloadAction(Request $request, Application $app, $gist, $commit) + public function downloadAction(Request $request, $gist, $commit) { - $viewOptions = $this->getViewOptions($request, $app, $gist, $commit); + $app = $this->getApp(); + + $viewOptions = $this->getViewOptions($request, $gist, $commit); if (is_array($viewOptions)) { $gist = $viewOptions['gist']; @@ -88,18 +94,20 @@ class ViewController extends Controller } } - public function revisionsAction(Request $request, Application $app, $gist) + public function revisionsAction(Request $request, $gist) { + $app = $this->getApp(); + $gist = GistQuery::create()->findOneByFile($gist); if (null === $gist) { - return $this->notFoundResponse($app); + return $this->notFoundResponse(); } $history = $app['gist']->getHistory($gist); if (empty($history)) { - return $this->notFoundResponse($app); + return $this->notFoundResponse(); } return $this->render( @@ -107,8 +115,7 @@ class ViewController extends Controller array( 'gist' => $gist, 'history' => $history, - ), - $app + ) ); } } diff --git a/src/Gist/ControllerResolver.php b/src/Gist/ControllerResolver.php new file mode 100644 index 0000000..6da4ff3 --- /dev/null +++ b/src/Gist/ControllerResolver.php @@ -0,0 +1,19 @@ + + */ +class ControllerResolver extends BaseControllerResolver +{ + protected function instantiateController($class) + { + return new $class($this->app); + } +} + diff --git a/src/Gist/Resources/config/propel/schema.xml b/src/Gist/Resources/config/propel/schema.xml index b85460c..21fbab5 100644 --- a/src/Gist/Resources/config/propel/schema.xml +++ b/src/Gist/Resources/config/propel/schema.xml @@ -1,6 +1,6 @@ - +
@@ -15,7 +15,7 @@
- +
diff --git a/src/Gist/Security/AuthenticationEntryPoint.php b/src/Gist/Security/AuthenticationEntryPoint.php new file mode 100644 index 0000000..8a09fda --- /dev/null +++ b/src/Gist/Security/AuthenticationEntryPoint.php @@ -0,0 +1,41 @@ + + */ +class AuthenticationEntryPoint implements AuthenticationEntryPointInterface +{ + protected $urlGenerator; + + public function __construct(UrlGenerator $urlGenerator) + { + $this->urlGenerator = $urlGenerator; + } + + public function start(Request $request, AuthenticationException $authException = null) + { + if ($request->isXmlHttpRequest()) { + $response = new Response(json_encode([]), 401); + $response->headers->set('Content-Type', 'application/json'); + + return $response; + } + + if ($authException->getMessage() !== 'Full authentication is required to access this resource.') { + $params = ['error' => 1]; + } else { + $params = []; + } + + return new RedirectResponse($this->urlGenerator->generate('_login', $params)); + } +} diff --git a/src/Gist/Security/AuthenticationListener.php b/src/Gist/Security/AuthenticationListener.php new file mode 100644 index 0000000..a4b125d --- /dev/null +++ b/src/Gist/Security/AuthenticationListener.php @@ -0,0 +1,50 @@ + + */ +class AuthenticationListener implements ListenerInterface +{ + protected $tokenStorage; + + protected $authenticationManager; + + public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager) + { + $this->tokenStorage = $tokenStorage; + $this->authenticationManager = $authenticationManager; + } + + public function handle(GetResponseEvent $event) + { + $request = $event->getRequest(); + $username = $request->get('_username'); + $password = $request->get('_password'); + + if (!empty($username)) { + $token = new UsernamePasswordToken($username, $password, 'default'); + + try { + $authToken = $this->authenticationManager->authenticate($token); + $this->tokenStorage->setToken($token); + + return; + } catch (AuthenticationException $failed) { + $this->tokenStorage->setToken(null); + + return; + } + } + } +} diff --git a/src/Gist/Security/AuthenticationProvider.php b/src/Gist/Security/AuthenticationProvider.php new file mode 100644 index 0000000..e0f0b85 --- /dev/null +++ b/src/Gist/Security/AuthenticationProvider.php @@ -0,0 +1,49 @@ + + */ +class AuthenticationProvider implements AuthenticationProviderInterface +{ + protected $userProvider; + + public function __construct(UserProvider $userProvider) + { + $this->userProvider = $userProvider; + } + + public function authenticate(TokenInterface $token) + { + $user = $this->userProvider->loadUserByUsername($token->getUser()); + + if ($user) { + $isValid = $this->userProvider->getEncoder()->isPasswordValid( + $user->getPassword(), + $token->getCredentials(), + $user->getSalt() + ); + + if (!$isValid) { + throw new AuthenticationException('Authentication failed.'); + } + + return; + } + + throw new AuthenticationException('Authentication failed.'); + } + + public function supports(TokenInterface $token) + { + return $token instanceof UsernamePasswordToken; + } +} diff --git a/src/Gist/Service/GistService.php b/src/Gist/Service/Gist.php similarity index 86% rename from src/Gist/Service/GistService.php rename to src/Gist/Service/Gist.php index 4010101..4c1bde5 100644 --- a/src/Gist/Service/GistService.php +++ b/src/Gist/Service/Gist.php @@ -2,18 +2,19 @@ namespace Gist\Service; -use Gist\Model\Gist; +use Gist\Model\Gist as GistModel; use GitWrapper\GitWorkingCopy; use GitWrapper\GitWrapper; use GitWrapper\GitCommand; use GeSHi; use Gist\Model\GistQuery; +use Gist\Model\User; /** - * Class GistService + * Class Gist * @author Simon Vieille */ -class GistService +class Gist { protected $gistPath; @@ -36,7 +37,7 @@ class GistService return GistQuery::create()->find(); } - public function getHistory(Gist $gist) + public function getHistory(GistModel $gist) { $command = GitCommand::getInstance('log', '--format=medium', $gist->getFile()); $command->setDirectory($this->gistPath); @@ -70,7 +71,7 @@ class GistService return $history; } - public function getContent(Gist $gist, $commit) + public function getContent(GistModel $gist, $commit) { $command = GitCommand::getInstance('cat-file', '-p', $commit.':'.$gist->getFile()); $command->setDirectory($this->gistPath); @@ -79,7 +80,7 @@ class GistService return $this->gitWrapper->run($command); } - public function create(Gist $gist, array $data) + public function create(GistModel $gist, array $data, $user = null) { $gist->hydrateWith($data); $gist->generateFilename(); @@ -90,12 +91,16 @@ class GistService ->add($gist->getFile()) ->commit('Init'); + if (is_object($user) && $user instanceof User) { + $gist->setUser($user); + } + $gist->save(); return $gist; } - public function commit(Gist $gist, array $data) + public function commit(GistModel $gist, array $data) { file_put_contents($this->gistPath.'/'.$gist->getFile(), $data['content']);