Commit c8cc3a81 authored by Avris's avatar Avris

init

parents
App/parameters.yml
App/parameters.yml.local
App/parameters.yml.build
cache/*
logs/*
attachments/*
!cache/.gitkeep
!logs/.gitkeep
!attachments/.gitkeep
vendor/*
build.php
_home/*
.idea/*
desktop.ini
\ No newline at end of file
<?php
namespace App\Controller;
use Avris\Micrus\Controller;
use Avris\Micrus\Exception\InvalidArgumentException;
use Avris\Micrus\Http\Response;
use App\Form\FolderForm;
use App\Model\Folder;
class FolderController extends Controller
{
public function showPersonalAction()
{
return $this->render(array(
'keys' => \R::find('key', 'user_id = ?', array($this->getUser()->id)),
));
}
public function showAction(Folder $folder)
{
return $this->render(array(
'folder' => $folder,
'personalkeys' => $folder->folder === null ? \R::find('key', 'user_id = ?', array($this->getUser()->id)) : array(),
));
}
public function addAction(Folder $parent)
{
$folder = \R::dispense('folder');
$folder->folder = $parent;
return $this->form($folder->box());
}
public function editAction(Folder $folder)
{
return $this->form($folder);
}
public function form(Folder $folder)
{
$form = new FolderForm($folder, array(
'folder' => $folder->id ? $folder : null,
));
$form->bind($this->getPost());
if ($form->isValid()) {
\R::store($form->getFolder());
return new Response('OK');
}
return $this->render(array(
'_view' => 'Folder/form.html.twig',
'folder' => $folder,
'form' => $form,
));
}
public function removeAction(Folder $folder)
{
if (!$folder->folder) { throw new InvalidArgumentException('Cannot delete root folder'); }
$folder->remove();
return new Response('OK');
}
}
\ No newline at end of file
<?php
namespace App\Controller;
use App\Form\InstallForm;
use App\Task\FixturesTask;
use Avris\Micrus\Controller;
class HomeController extends Controller {
public function homeAction()
{
return $this->render();
}
public function installerAction()
{
if ($this->getParameter('installed')) { return $this->redirectToRoute('home'); }
$rootDir = $this->getApp()->getRootDir();
foreach (array('App/parameters.yml', 'cache', 'logs') as $path) {
if (!is_writable($rootDir . '/' . $path)) {
throw new \Exception(sprintf('"%s" is not writable. Please change its permissions', $path));
}
}
if (!$this->getParameter('secret')) {
file_put_contents($rootDir . '/App/parameters.yml', \Spyc::YAMLDump(array(
'installed' => false,
'secret' => hash('sha256', mt_rand()),
)));
}
$form = new InstallForm(null, array(
'app' => $this->getApp(),
));
$form->bind($this->getPost());
if ($form->isValid()) {
$fixtures = new FixturesTask($this->getApp());
$fixtures->load();
$dbParams = $form->getDatabaseParams($form->getObject());
$dbParams['freeze'] = true;
switch ($dbParams['driver']) {
case 'mysql':
\R::exec('SET FOREIGN_KEY_CHECKS=0');
$this->wipeAll();
\R::exec('SET FOREIGN_KEY_CHECKS=1');
break;
case 'pgsql':
\R::exec('SET CONSTRAINTS ALL DEFERRED');
$this->wipeAll();
\R::exec('SET CONSTRAINTS ALL IMMEDIATE');
break;
case 'sqlite':
\R::exec('PRAGMA foreign_keys = 0');
$this->wipeAll();
\R::exec('PRAGMA foreign_keys = 1');
break;
default:
}
$admin = \R::dispense('user');
$admin->username = $form->getObject()->admin_mail;
$admin->password = $this->getService('crypt')->hash($form->getObject()->admin_pass);
$admin->role = 'ROLE_ADMIN';
$admin->token = '';
\R::store($admin);
$folder = \R::dispense('folder');
$folder->icon = 'home';
$folder->name = 'Home';
$folder->public = true;
\R::store($folder);
file_put_contents($rootDir . '/App/parameters.yml', \Spyc::YAMLDump(array(
'installed' => true,
'database' => $dbParams,
'mailer' => $form->getMailerParams($form->getObject()),
'secret' => $this->getParameter('secret'),
)));
$this->addFlash('success', $this->getService('localizator')->get('Configuration set up successfully'));
return $this->redirectToRoute('login');
}
return $this->render(array('form' => $form));
}
private function wipeAll()
{
foreach (\R::inspect() as $table) {
\R::wipe($table);
}
}
}
\ No newline at end of file
<?php
namespace App\Controller;
use Avris\Micrus\Controller;
use Avris\Micrus\Http\Request;
use Avris\Micrus\Http\Response;
use Avris\Micrus\Exception\NotFoundException;
use App\Form\KeyForm;
use App\Model\Folder;
use App\Model\Key;
class KeyController extends Controller
{
public function addAction(Folder $folder = null)
{
$key = \R::dispense('key');
if ($folder) {
$key->folder = $folder;
} else {
$key->user = $this->getUser();
}
return $this->form($key->box());
}
public function showAction(Key $key)
{
return $this->render(array(
'key' => $key,
'password' => $this->getService('crypt')->decrypt($key->password),
));
}
public function editAction(Key $key)
{
return $this->form($key);
}
private function form(Key $key)
{
$form = new KeyForm($key , array(
'crypt' => $this->getService('crypt'),
));
$form->bind($this->getPost());
if ($form->isValid()) {
\R::store($form->getObject());
return new Response('OK');
}
return $this->render(array(
'_view' => 'Key/form.html.twig',
'key' => $key,
'form' => $form,
));
}
public function changesAction(Key $key)
{
$users = array();
foreach (\R::findAll('user') as $user) { $users[$user['id']] = $user['username']; }
return $this->render(array(
'key' => $key,
'users' => $users,
));
}
public function attachAction(Request $request, Key $key)
{
if ($file = $request->getFiles('file')) {
$this->backupOldAttachment($key);
copy($file['tmp_name'], $this->getAttachmentPath($key));
$key->attachment = $file['name'];
\R::store($key);
return $this->renderJson(array(
'jsonrpc' => '2.0',
'result' => null,
'id' => 'id',
'filename' => $file['name'],
'original_filename' => $file['name'],
));
}
return $this->renderJson(array(
'error' => 'No file sent',
));
}
public function downloadAction(Key $key)
{
$filename = $this->getAttachmentPath($key);
if (!$key->attachment || !file_exists($filename)) { throw new NotFoundException('This key doesn\'t have any attachment'); }
return new Response(file_get_contents($filename), 200, array(
'Content-Disposition' => 'attachment; filename="'.$key->attachment.'"',
));
}
public function removeAttachmentAction(Key $key)
{
if (!$key->attachment) { throw new NotFoundException('This key doesn\'t have any attachment'); }
$this->backupOldAttachment($key);
@unlink($this->getAttachmentPath($key));
$key->attachment = null;
\R::store($key);
return new Response('OK');
}
private function getAttachmentPath(Key $key)
{
return $this->getApp()->getRootDir() . '/attachments/' . $key->id;
}
private function backupOldAttachment(Key $key)
{
$filename = $this->getAttachmentPath($key);
if (!file_exists($filename)) { return; }
rename($filename, $filename . '_' . time('YmdHis'));
}
public function removeAction(Key $key)
{
\R::trash($key);
return new Response('OK');
}
}
\ No newline at end of file
<?php
namespace App\Controller;
use Avris\Micrus\Controller;
use App\Form\UserForm;
use Avris\Micrus\Exception\NotFoundException;
use Avris\Micrus\Http\Request;
use App\Form\PasswordForm;
use App\Model\User;
use App\Form\LoginForm;
use App\Form\RemindForm;
class UserController extends Controller
{
public function loginAction()
{
if ($this->getUser()) {
return $this->redirectToRoute('home');
}
$form = new LoginForm(\R::dispense('user'), array(
'localizator' => $this->getService('localizator'),
'crypt' => $this->getService('crypt'),
));
$form->bind($this->getPost());
if ($form->isValid()) {
$user = $form->getUser();
$this->getService('crypt')->login($user, $form->shouldRememberHim());
$url = $this->getRequest()->getGet('url');
return $this->redirect($url ?
$this->getRouter()->prependToUrl($url) :
$this->generateUrl('home'));
}
return $this->render(array('form' => $form));
}
public function remindAction()
{
if ($this->getUser()) {
return $this->redirectToRoute('home');
}
$form = new RemindForm();
$form->bind($this->getPost());
if ($form->isValid()) {
$user = $form->getUser();
$token = sha1(uniqid());
$user->token = $token;
\R::store($user);
$this->sendMail('mail.remind', $user->username, $token);
$this->addFlash('success', $this->getService('localizator')->get('Password resetting email has been sent to you'));
return $this->redirectToRoute('login');
}
return $this->render(array('form' => $form));
}
public function remindTokenAction($token)
{
$user = \R::findOne('user', 'token = ?', array($token));
if (!$user) { throw new NotFoundException; }
$password = $this->generatePassword();
$user->token = null;
$user->password = $this->getService('crypt')->hash($password);
\R::store($user);
$this->getService('crypt')->login($user, false);
$this->addFlash('success', $this->getService('localizator')->get('Your password has been set to "%pass%". You can change it in the form below.', array('%pass%' => $password)));
return $this->redirectToRoute('account');
}
public function accountAction()
{
$form = new PasswordForm($this->getUser());
$form->bind($this->getPost());
if ($form->isValid()) {
$this->addFlash('success', $this->getService('localizator')->get(
'Your password has been changed'));
\R::store($form->getUser($this->getService('crypt')));
return $this->redirectToRoute('account');
}
return $this->render(array(
'form' => $form,
));
}
public function listAction()
{
return $this->render(array(
'users' => \R::findAll('user'),
));
}
public function addAction()
{
$form = new UserForm(\R::dispense('user'));
$form->bind($this->getPost());
if ($form->isValid()) {
$user = $form->getUser();
$user->password = $this->getService('crypt')->hash($this->generatePassword());
$user->token = sha1(uniqid());
\R::store($user);
$this->sendMail('mail.welcome', $user->username, $user->token);
$this->addFlash('success', $this->getService('localizator')->get(
'User has been created and their password sent to %email%',
array('%email%' => $user->username)));
return $this->redirectToRoute('users');
}
return $this->render(array(
'_view' => 'User/form.html.twig',
'form' => $form,
'header' => 'Create new user',
));
}
public function editAction(User $user)
{
$form = new UserForm($user, array(
'user' => $user,
));
$form->bind($this->getPost());
if ($form->isValid()) {
\R::store($form->getUser());
$this->addFlash('success', $this->getService('localizator')->get(
'User data have been saved'));
return $this->redirectToRoute('userEdit', array('id' => $user->id));
}
return $this->render(array(
'_view' => 'User/form.html.twig',
'form' => $form,
'header' => 'Edit user data',
));
}
public function removeAction(Request $request, User $user)
{
if ($user->id == $this->getUser()->id) {
$this->addFlash('danger', $this->getService('localizator')->get(
'You cannot remove your own account'));
return $this->redirectToRoute('users');
}
if ($request->isPost()) {
\R::trashAll($user->ownKey);
\R::trash($user);
$this->addFlash('success', $this->getService('localizator')->get(
'User account has been removed'));
return $this->redirectToRoute('users');
}
return $this->render(array('user' => $user));
}
private function generatePassword()
{
return substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
}
private function sendMail($template, $email, $token)
{
$localizator = $this->getService('localizator');
$this->getService('mailer')->send($localizator->get($template.'.subject'),
$localizator->get($template.'.body', array(
'%host%' => $this->getRequest()->getServer('HTTP_HOST'),
'%email%' => $email,
'%token%' => $token,
)),
array($email => $email)
);
}
}
\ No newline at end of file
<?php
namespace App\Form;
use Avris\Micrus\Form;
use Avris\Micrus\Assert as Assert;
use Avris\Micrus\FormStyle\Bootstrap2;
class FolderForm extends Form
{
public function configure()
{
$this
->setStyle(new Bootstrap2)
->add('icon', 'IconChoice', array('label' => '[[Icon]]'), new Assert\NotBlank())
->add('name', 'Text', array('label' => '[[Name]]'), new Assert\NotBlank())
->add('public', 'Checkbox', array('label' => '[[Public]]'))
;
if ($folder = $this->options->get('folder')) {
$this->add('ownPermissionList', 'Permission', array(
'label' => '[[Permissions]]',
'staticSide' => array('folder', $folder),
'dynamicSide' => 'user'
));
}
}
public function getFolder($clearCsrf = true)
{
$object = parent::getObject($clearCsrf);
$folder = $this->options->get('folder');
if ($folder && $folder->id) { \R::trashAll(\R::findAll('permission', 'folder_id = ?', array($folder->id))); }
return $object;
}
}
\ No newline at end of file
<?php
namespace App\Form;
use App\Service\Mailer;
use Avris\Micrus\Form;
use Avris\Micrus\Assert as Assert;
use Avris\Micrus\FormStyle\Bootstrap2;
use Avris\Micrus\IO\ConfigLoader;
class InstallForm extends Form
{
public function configure()
{
$this
->setStyle(new Bootstrap2)
->with('[[Database]]')
->add('db_driver', 'Choice', array('label' => '[[Driver]]', 'choices' => array(
'mysql' => 'MySQL',
'pgsql' => 'PostgreSQL',
'sqlite' => 'SQLite',
'cubrid' => 'CUBRID',
)), new Assert\NotBlank())
->add('db_correct', 'ObjectValidator', array('callback' => array($this, 'checkDbCorrect')))
->add('db_host', 'Text', array('label' => '[[Host]]', 'attr' => array('class' => 'dbHide mysql pgsql cubrid')))
->add('db_port', 'Number', array('label' => '[[Port]]', 'attr' => array('class' => 'dbHide cubrid')))
->add('db_name', 'Text', array('label' => '[[Database]]', 'attr' => array('class' => 'dbHide mysql pgsql cubrid')))
->add('db_user', 'Text', array('label' => '[[Username]]', 'attr' => array('class' => 'dbHide mysql pgsql cubrid')))
->add('db_pass', 'Text', array('label' => '[[Password]]', 'attr' => array('class' => 'dbHide mysql pgsql cubrid')))
->add('db_file', 'Text', array('label' => '[[Filename]]', 'attr' => array('class' => 'dbHide sqlite')))
->end()
->with('SMTP Connection')
->add('mailer_correct', 'ObjectValidator', array('callback' => array($this, 'checkMailerCorrect')))
->add('mailer_host', 'Text', array('label' => '[[Host]]'), new Assert\NotBlank())
->add('mailer_port', 'Number', array('label' => '[[Port]]'), array(new Assert\NotBlank(), new Assert\Min(1)))
->add('mailer_secure', 'Choice', array('label' => '[[Secure]]', 'choices' => array(
'false' => '',
'ssl' => 'SSL',
'ttl' => 'TTL',
)), new Assert\NotBlank())
->add('mailer_username', 'Text', array('label' => '[[Username]]'), new Assert\NotBlank())
->add('mailer_password', 'Text', array('label' => '[[Password]]'), new Assert\NotBlank())
->add('mailer_sender', 'Email', array('label' => '[[Sender email]]'), new Assert\NotBlank())
->end()
->with('Admin account')
->add('admin_mail', 'Email', array('label' => '[[Email]]'), new Assert\NotBlank())
->add('admin_pass', 'ClavisPassword', array(
'label' => '[[Password]]',
'strength' => true,
'generator' => true,
),
array(new Assert\NotBlank(), new Assert\MinLength(8)))
->end()
;
$this->object->db_host = 'localhost';
$this->object->db_name = 'clavis';
$this->object->db_file = 'clavis.s3db';
$this->object->mailer_smtp = true;
}
public function checkDbCorrect($data)
{
\R::$toolboxes = array();
$loader = new ConfigLoader($this->options->get('app'));
\R::$currentDB = '';
$loader->configDatabase(array('database' => $this->getDatabaseParams($data)));
if (!\R::testConnection()) { return '[[Cannot connect to the database]]'; }
return true;
}
public function checkMailerCorrect($data)
{
$mailer = new Mailer($this->getMailerParams($data));
if (!$mailer->testConnection()) { return '[[Cannot connect to SMTP server]]'; }
return true;
}
public function getDatabaseParams($data)
{
$out = array();
foreach (array('driver', 'host', 'port', 'name', 'user', 'pass', 'file') as $attr) {
$out[$attr] = $data->{'db_'.$attr};
}
return $out;
}
public function getMailerParams($data)
{
$out = array();
foreach (array('host', 'port', 'secure', 'username', 'password', 'sender') as $attr) {
$out[$attr] = $data->{'mailer_'.$attr};
}
return $out;
}
}
\ No newline at end of file
<?php
namespace App\Form;