Commit dc506217 authored by Nicolas Widart's avatar Nicolas Widart

Squashed 'Modules/User/' content from commit 75dc3fb

git-subtree-dir: Modules/User
git-subtree-split: 75dc3fb74bf277d756c58c7ed0f5e5fd22c62ed9
parents
.idea/
/vendor
.php_cs.cache
composer.lock
Modules/
build
<?php
$finder = Symfony\CS\Finder\DefaultFinder::create()
->exclude('Modules')
->exclude('vendor')
->in(__DIR__)
;
return Symfony\CS\Config\Config::create()
->setUsingCache(true)
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers(array(
// Concatenation should be used with at least one whitespace around.
'concat_with_spaces',
// Unused use statements must be removed.
'ordered_use',
// Removes extra empty lines.
'extra_empty_lines',
// Removes line breaks between use statements.
'remove_lines_between_uses',
// An empty line feed should precede a return statement.
'return',
// Unused use statements must be removed.
'unused_use',
// Remove trailing whitespace at the end of blank lines.
'whitespacy_lines',
// There MUST be one blank line after the namespace declaration.
'line_after_namespace',
// There should be exactly one blank line before a namespace declaration.
'single_blank_line_before_namespace',
// Each namespace use MUST go on its own line and there MUST be one blank line after the use statements block.
'single_line_after_imports',
// Ensure there is no code on the same line as the PHP open tag and it is followed by a blankline.
'blankline_after_open_tag',
// Remove duplicated semicolons.
'duplicate_semicolon',
// PHP multi-line arrays should have a trailing comma.
'multiline_array_trailing_comma',
// There should be no empty lines after class opening brace.
'no_blank_lines_after_class_opening',
// There should not be blank lines between docblock and the documented element.
'no_empty_lines_after_phpdocs',
// Phpdocs should start and end with content, excluding the very first and last line of the docblocks.
'phpdoc_trim',
// Removes line breaks between use statements.
'remove_lines_between_uses',
))
->finder($finder);
filter:
excluded_paths: [tests/*]
checks:
php:
code_rating: true
remove_extra_empty_lines: true
remove_php_closing_tag: true
remove_trailing_whitespace: true
fix_use_statements:
remove_unused: true
preserve_multiple: false
preserve_blanklines: true
order_alphabetically: true
fix_php_opening_tag: true
fix_linefeed: true
fix_line_ending: true
fix_identation_4spaces: true
fix_doc_comments: true
tools:
external_code_coverage:
timeout: 600
runs: 3
php_analyzer: true
php_code_coverage: false
php_code_sniffer:
config:
standard: PSR2
filter:
paths: ['src']
php_loc:
enabled: true
excluded_dirs: [vendor, tests]
php_cpd:
enabled: true
excluded_dirs: [vendor, tests]
rules:
php.interface_has_no_interface_suffix:
enabled: false
language: php
php:
- 7
- 5.6
- hhvm
env:
- LARAVEL_VERSION="~5.2" TESTBENCH_VERSION="~3.2"
before_script:
- travis_retry composer install --no-interaction --prefer-source
script: phpunit
sudo: false
notifications:
email:
- n.widart@gmail.com
- josh@joshbrown.me
matrix:
allow_failures:
- php: hhvm
<?php
namespace Modules\User\Composers;
use Modules\User\Permissions\PermissionManager;
class PermissionsViewComposer
{
/**
* @var PermissionManager
*/
private $permissions;
public function __construct(PermissionManager $permissions)
{
$this->permissions = $permissions;
}
public function compose($view)
{
// Get all permissions
$view->permissions = $this->permissions->all();
}
}
<?php
namespace Modules\User\Composers;
use Illuminate\Contracts\View\View;
use Modules\User\Contracts\Authentication;
class UsernameViewComposer
{
/**
* @var Authentication
*/
private $auth;
public function __construct(Authentication $auth)
{
$this->auth = $auth;
}
public function compose(View $view)
{
$view->with('user', $this->auth->user());
}
}
<?php
return [
/*
|--------------------------------------------------------------------------
| Define which user driver to use.
|--------------------------------------------------------------------------
| Current default and only option : Sentinel
*/
'driver' => 'Sentinel',
/*
|--------------------------------------------------------------------------
| Define which route to redirect to after a successful login
|--------------------------------------------------------------------------
*/
'redirect_route_after_login' => 'homepage',
/*
|--------------------------------------------------------------------------
| Define which route the user should be redirected to after accessing
| a resource that requires to be logged in
|--------------------------------------------------------------------------
*/
'redirect_route_not_logged_in' => 'auth/login',
/*
|--------------------------------------------------------------------------
| Login column(s)
|--------------------------------------------------------------------------
| Define which column(s) you'd like to use to login with, currently
| only supported by the Sentinel user driver
*/
'login-columns' => ['email'],
/*
|--------------------------------------------------------------------------
| Allow anonymous user registration
|--------------------------------------------------------------------------
*/
'allow_user_registration' => true,
/*
|--------------------------------------------------------------------------
| The default role for new user registrations
| Default: User
|--------------------------------------------------------------------------
*/
'default_role' => 'User',
/*
|--------------------------------------------------------------------------
| Fillable user fields
|--------------------------------------------------------------------------
| Set the fillable user fields, those fields will be mass assigned
*/
'fillable' => [
'email',
'password',
'permissions',
'first_name',
'last_name',
],
/*
|--------------------------------------------------------------------------
| Dynamic relations
|--------------------------------------------------------------------------
| Add relations that will be dynamically added to the User entity
*/
'relations' => [
// 'extension' => function ($self) {
// return $self->belongsTo(UserExtension::class, 'user_id', 'id')->first();
// }
],
/*
|--------------------------------------------------------------------------
| Custom Sidebar Class
|--------------------------------------------------------------------------
| If you want to customise the admin sidebar ordering or grouping
| You can define your own sidebar class for this module.
| No custom sidebar: null
*/
'custom-sidebar' => null,
];
<?php
return [
'user.users' => [
'index' => 'user::users.list user',
'create' => 'user::users.create user',
'edit' => 'user::users.edit user',
'destroy' => 'user::users.destroy user',
],
'user.roles' => [
'index' => 'user::roles.list resource',
'create' => 'user::roles.create resource',
'edit' => 'user::roles.edit resource',
'destroy' => 'user::roles.destroy resource',
],
'account.api-keys' => [
'index' => 'user::users.list api key',
'create' => 'user::users.create api key',
'destroy' => 'user::users.destroy api key',
],
];
<?php
namespace Modules\User\Contracts;
interface Authentication
{
/**
* Authenticate a user
* @param array $credentials
* @param bool $remember Remember the user
* @return mixed
*/
public function login(array $credentials, $remember = false);
/**
* Register a new user.
* @param array $user
* @return bool
*/
public function register(array $user);
/**
* Activate the given used id
* @param int $userId
* @param string $code
* @return mixed
*/
public function activate($userId, $code);
/**
* Assign a role to the given user.
* @param \Modules\User\Repositories\UserRepository $user
* @param \Modules\User\Repositories\RoleRepository $role
* @return mixed
*/
public function assignRole($user, $role);
/**
* Log the user out of the application.
* @return mixed
*/
public function logout();
/**
* Create an activation code for the given user
* @param $user
* @return mixed
*/
public function createActivation($user);
/**
* Create a reminders code for the given user
* @param $user
* @return mixed
*/
public function createReminderCode($user);
/**
* Completes the reset password process
* @param $user
* @param string $code
* @param string $password
* @return bool
*/
public function completeResetPassword($user, $code, $password);
/**
* Determines if the current user has access to given permission
* @param $permission
* @return bool
*/
public function hasAccess($permission);
/**
* Check if the user is logged in
* @return bool
*/
public function check();
/**
* Get the currently logged in user
* @return \Modules\User\Entities\UserInterface
*/
public function user();
/**
* Get the ID for the currently authenticated user
* @return int
*/
public function id();
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateUserTokensTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('user_tokens', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('access_token');
$table->timestamps();
$table->unique('access_token');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::drop('user_tokens');
}
}
<?php
namespace Modules\User\Database\Seeders;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
class SentinelGroupSeedTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
$groups = Sentinel::getRoleRepository();
// Create an Admin group
$groups->createModel()->create(
[
'name' => 'Admin',
'slug' => 'admin',
]
);
// Create an Users group
$groups->createModel()->create(
[
'name' => 'User',
'slug' => 'user',
]
);
// Save the permissions
$group = Sentinel::findRoleBySlug('admin');
$group->permissions = [
'dashboard.index' => true,
'dashboard.update' => true,
'dashboard.reset' => true,
/* Workbench */
'workshop.modules.index' => true,
'workshop.modules.show' => true,
'workshop.modules.disable' => true,
'workshop.modules.enable' => true,
'workshop.modules.update' => true,
'workshop.themes.index' => true,
'workshop.themes.show' => true,
/* Roles */
'user.roles.index' => true,
'user.roles.create' => true,
'user.roles.edit' => true,
'user.roles.destroy' => true,
/* Users */
'user.users.index' => true,
'user.users.create' => true,
'user.users.edit' => true,
'user.users.destroy' => true,
/* API keys */
'account.api-keys.index' => true,
'account.api-keys.create' => true,
'account.api-keys.destroy' => true,
/* Menu */
'menu.menus.index' => true,
'menu.menus.create' => true,
'menu.menus.edit' => true,
'menu.menus.destroy' => true,
'menu.menuitems.index' => true,
'menu.menuitems.create' => true,
'menu.menuitems.edit' => true,
'menu.menuitems.destroy' => true,
/* Media */
'media.medias.index' => true,
'media.medias.create' => true,
'media.medias.edit' => true,
'media.medias.destroy' => true,
/* Settings */
'setting.settings.index' => true,
'setting.settings.edit' => true,
/* Page */
'page.pages.index' => true,
'page.pages.create' => true,
'page.pages.edit' => true,
'page.pages.destroy' => true,
/* Translation */
'translation.translations.index' => true,
'translation.translations.edit' => true,
'translation.translations.export' => true,
'translation.translations.import' => true,
/* Tags */
'tag.tags.index' => true,
'tag.tags.create' => true,
'tag.tags.edit' => true,
'tag.tags.destroy' => true,
];
$group->save();
}
}
<?php
namespace Modules\User\Database\Seeders;
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
class SentinelUserSeedTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
// Create an admin user
$user = Sentinel::create(
[
'email' => 'n.widart@gmail.com',
'password' => 'test',
'first_name' => 'Nicolas',
'last_name' => 'Widart',
]
);
// Activate the admin directly
$activation = Activation::create($user);
Activation::complete($user, $activation->code);
// Find the group using the group id
$adminGroup = Sentinel::findRoleBySlug('admin');
// Assign the group to the user
$adminGroup->users()->attach($user);
}
}
<?php
namespace Modules\User\Database\Seeders;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
class UserDatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
$this->call(SentinelGroupSeedTableSeeder::class);
}
}
<?php
namespace Modules\User\Emails;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Modules\User\Entities\UserInterface;
class WelcomeEmail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
/**
* @var UserInterface
*/
public $user;
/**
* @var
*/
public $activationCode;
protected $subject = 'Welcome.';
public function __construct(UserInterface $user, $activationCode)
{
$this->user = $user;
$this->activationCode = $activationCode;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('user::emails.welcome');
}
}
<?php
namespace Modules\User\Entities\Sentinel;
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Cartalyst\Sentinel\Users\EloquentUser;
use Laracasts\Presenter\PresentableTrait;
use Modules\User\Entities\UserInterface;
use Modules\User\Entities\UserToken;
use Modules\User\Presenters\UserPresenter;
class User extends EloquentUser implements UserInterface
{
use PresentableTrait;
protected $fillable = [
'email',
'password',
'permissions',
'first_name',
'last_name',
];
/**
* {@inheritDoc}
*/
protected $loginNames = ['email'];
protected $presenter = UserPresenter::class;
public function __construct(array $attributes = [])
{
$this->loginNames = config('asgard.user.config.login-columns');
$this->fillable = config('asgard.user.config.fillable');
parent::__construct($attributes);
}
/**
* Checks if a user belongs to the given Role ID
* @param int $roleId
* @return bool
*/
public function hasRoleId($roleId)
{
return $this->roles()->whereId($roleId)->count() >= 1;
}
/**
* Checks if a user belongs to the given Role Name
* @param string $name
* @return bool
*/
public function hasRoleName($name)
{
return $this->roles()->whereName($name)->count() >= 1;
}
/**
* Check if the current user is activated
* @return bool
*/
public function isActivated()
{
if (Activation::completed($this)) {
return true;
}
return false;
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function api_keys()
{
return $this->hasMany(UserToken::class);
}
/**
* Get the first available api key
* @return string
*/
public function getFirstApiKey()
{
$userToken = $this->api_keys->first();
if ($userToken === null) {
return '';
}
return $userToken->access_token;
}
public function __call($method, $parameters)
{
#i: Convert array to dot notation
$config = implode('.', ['asgard.user.config.relations', $method]);
#i: Relation method resolver
if (config()->has($config)) {
$function = config()->get($config);
return $function($this);
}
#i: No relation found, return the call to parent (Eloquent) to handle it.
return parent::__call($method, $parameters);
}
/**
* Check if the user has access to the given permission name
* @param string $permission
* @return boolean
*/
public function hasAccess($permission)
{
$permissions = $this->getPermissionsInstance();
return $permissions->hasAccess($permission);
}
}
<?php
namespace Modules\User\Entities;
interface UserInterface
{
/**
* Checks if a user belongs to the given Role ID
* @param int $roleId
* @return bool
*/
public function hasRoleId($roleId);
/**
* Checks if a user belongs to the given Role Name
* @param string $name
* @return bool
*/
public function hasRoleName($name);
/**
* Check if the current user is activated
* @return bool
*/
public function isActivated();
/**
* Get the first available api key
* @return string
*/
public function getFirstApiKey();
/**
* Check if the user has access to the given permission name
* @param string $permission
* @return boolean
*/
public function hasAccess($permission);
}
<?php
namespace Modules\User\Entities;
use Illuminate\Database\Eloquent\Model;
use Modules\User\Entities\Sentinel\User;
class UserToken extends Model
{
protected $table = 'user_tokens';
protected $fillable = ['user_id', 'access_token'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
<?php
namespace Modules\User\Events\Handlers;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Support\Facades\Mail;
use Modules\User\Contracts\Authentication;
use Modules\User\Events\UserHasRegistered;
use Modules\User\Emails\WelcomeEmail;
class SendRegistrationConfirmationEmail
{
/**
* @var AuthenticationRepository
*/
private $auth;
/**
* @var Mailer
*/
private $mail;
public function __construct(Authentication $auth, Mailer $mail)
{
$this->auth = $auth;
$this->mail = $mail;
}
public function handle(UserHasRegistered $event)
{
$user = $event->user;
$activationCode = $this->auth->createActivation($user);
$this->mail->to($user->email)->send(new WelcomeEmail($user, $activationCode));
}
}
<?php
namespace Modules\User\Events\Handlers;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Modules\User\Events\UserHasBegunResetProcess;
class SendResetCodeEmail
{
public function handle(UserHasBegunResetProcess $event)
{
$user = $event->user;
$code = $event->code;
Mail::queue('user::emails.reminder', compact('user', 'code'), function (Message $m) use ($user) {
$m->to($user->email)->subject('Reset your account password.');
});
}
}
<?php
namespace Modules\User\Events;
class RoleWasUpdated
{
public $role;
public function __construct($role)
{
$this->role = $role;
}
}
<?php
namespace Modules\User\Events;
class UserHasActivatedAccount
{
public $user;
public function __construct($user)
{
$this->user = $user;
}
}
<?php
namespace Modules\User\Events;
class UserHasBegunResetProcess
{
public $user;
public $code;
public function __construct($user, $code)
{
$this->user = $user;
$this->code = $code;
}
}
<?php
namespace Modules\User\Events;
class UserHasRegistered
{
public $user;
public function __construct($user)
{
$this->user = $user;
}
}
<?php
namespace Modules\User\Events;
class UserWasUpdated
{
public $user;
public function __construct($user)
{
$this->user = $user;
}
}
<?php
namespace Modules\User\Exceptions;
use Exception;
class InvalidOrExpiredResetCode extends Exception
{
}
<?php
namespace Modules\User\Exceptions;
use Exception;
class UserNotFoundException extends Exception
{
}
<?php
namespace Modules\User\Http\Controllers\Admin\Account;
use Modules\Core\Http\Controllers\Admin\AdminBaseController;
use Modules\User\Contracts\Authentication;
use Modules\User\Entities\UserToken;
use Modules\User\Repositories\UserTokenRepository;
class ApiKeysController extends AdminBaseController
{
/**
* @var Authentication
*/
private $auth;
/**
* @var UserTokenRepository
*/
private $userToken;
public function __construct(Authentication $auth, UserTokenRepository $userToken)
{
parent::__construct();
$this->auth = $auth;
$this->userToken = $userToken;
}
public function index()
{
$tokens = $this->userToken->allForUser($this->auth->id());
$this->assetPipeline->requireJs('clipboard.js');
return view('user::admin.account.api-keys.index', compact('tokens'));
}
public function create()
{
$this->userToken->generateFor($this->auth->id());
return redirect()->route('admin.account.api.index')
->withSuccess(trans('user:users.token generated'));
}
public function destroy(UserToken $userToken)
{
$this->userToken->destroy($userToken);
return redirect()->route('admin.account.api.index')
->withSuccess(trans('core::core.messages.resource deleted', ['name' => 'Api Token']));
}
}
<?php
namespace Modules\User\Http\Controllers\Admin;
use Illuminate\Http\Request;
use Modules\Core\Http\Controllers\Admin\AdminBaseController;
use Modules\User\Permissions\PermissionManager;
abstract class BaseUserModuleController extends AdminBaseController
{
/**
* @var PermissionManager
*/
protected $permissions;
/**
* @param Request $request
* @return array
*/
protected function mergeRequestWithPermissions(Request $request)
{
$permissions = $this->permissions->clean($request->permissions);
return array_merge($request->all(), ['permissions' => $permissions]);
}
}
<?php
namespace Modules\User\Http\Controllers\Admin;
use Modules\User\Http\Requests\RolesRequest;
use Modules\User\Permissions\PermissionManager;
use Modules\User\Repositories\RoleRepository;
class RolesController extends BaseUserModuleController
{
/**
* @var RoleRepository
*/
private $role;
public function __construct(PermissionManager $permissions, RoleRepository $role)
{
parent::__construct();
$this->permissions = $permissions;
$this->role = $role;
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$roles = $this->role->all();
return view('user::admin.roles.index', compact('roles'));
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
return view('user::admin.roles.create');
}
/**
* Store a newly created resource in storage.
*
* @param RolesRequest $request
* @return Response
*/
public function store(RolesRequest $request)
{
$data = $this->mergeRequestWithPermissions($request);
$this->role->create($data);
return redirect()->route('admin.user.role.index')
->withSuccess(trans('user::messages.role created'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
if (!$role = $this->role->find($id)) {
return redirect()->route('admin.user.role.index')
->withError(trans('user::messages.role not found'));
}
return view('user::admin.roles.edit', compact('role'));
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @param RolesRequest $request
* @return Response
*/
public function update($id, RolesRequest $request)
{
$data = $this->mergeRequestWithPermissions($request);
$this->role->update($id, $data);
return redirect()->route('admin.user.role.index')
->withSuccess(trans('user::messages.role updated'));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
$this->role->delete($id);
return redirect()->route('admin.user.role.index')
->withSuccess(trans('user::messages.role deleted'));
}
}
<?php
namespace Modules\User\Http\Controllers\Admin;
use Modules\User\Contracts\Authentication;
use Modules\User\Events\UserHasBegunResetProcess;
use Modules\User\Http\Requests\CreateUserRequest;
use Modules\User\Http\Requests\UpdateUserRequest;
use Modules\User\Permissions\PermissionManager;
use Modules\User\Repositories\RoleRepository;
use Modules\User\Repositories\UserRepository;
class UserController extends BaseUserModuleController
{
/**
* @var UserRepository
*/
private $user;
/**
* @var RoleRepository
*/
private $role;
/**
* @var Authentication
*/
private $auth;
/**
* @param PermissionManager $permissions
* @param UserRepository $user
* @param RoleRepository $role
* @param Authentication $auth
*/
public function __construct(
PermissionManager $permissions,
UserRepository $user,
RoleRepository $role,
Authentication $auth
) {
parent::__construct();
$this->permissions = $permissions;
$this->user = $user;
$this->role = $role;
$this->auth = $auth;
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$users = $this->user->all();
$currentUser = $this->auth->user();
return view('user::admin.users.index', compact('users', 'currentUser'));
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
$roles = $this->role->all();
return view('user::admin.users.create', compact('roles'));
}
/**
* Store a newly created resource in storage.
*
* @param CreateUserRequest $request
* @return Response
*/
public function store(CreateUserRequest $request)
{
$data = $this->mergeRequestWithPermissions($request);
$this->user->createWithRoles($data, $request->roles, true);
return redirect()->route('admin.user.user.index')
->withSuccess(trans('user::messages.user created'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
if (!$user = $this->user->find($id)) {
return redirect()->route('admin.user.user.index')
->withError(trans('user::messages.user not found'));
}
$roles = $this->role->all();
$currentUser = $this->auth->user();
return view('user::admin.users.edit', compact('user', 'roles', 'currentUser'));
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @param UpdateUserRequest $request
* @return Response
*/
public function update($id, UpdateUserRequest $request)
{
$data = $this->mergeRequestWithPermissions($request);
$this->user->updateAndSyncRoles($id, $data, $request->roles);
return redirect()->route('admin.user.user.index')
->withSuccess(trans('user::messages.user updated'));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
$this->user->delete($id);
return redirect()->route('admin.user.user.index')
->withSuccess(trans('user::messages.user deleted'));
}
public function sendResetPassword($user, Authentication $auth)
{
$user = $this->user->find($user);
$code = $auth->createReminderCode($user);
event(new UserHasBegunResetProcess($user, $code));
return redirect()->route('admin.user.user.edit', $user->id)
->withSuccess(trans('user::auth.reset password email was sent'));
}
}
<?php
namespace Modules\User\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Modules\Core\Http\Controllers\BasePublicController;
use Modules\User\Exceptions\InvalidOrExpiredResetCode;
use Modules\User\Exceptions\UserNotFoundException;
use Modules\User\Http\Requests\LoginRequest;
use Modules\User\Http\Requests\RegisterRequest;
use Modules\User\Http\Requests\ResetCompleteRequest;
use Modules\User\Http\Requests\ResetRequest;
use Modules\User\Services\UserRegistration;
use Modules\User\Services\UserResetter;
class AuthController extends BasePublicController
{
use DispatchesJobs;
public function __construct()
{
parent::__construct();
}
public function getLogin()
{
return view('user::public.login');
}
public function postLogin(LoginRequest $request)
{
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
$remember = (bool) $request->get('remember_me', false);
$error = $this->auth->login($credentials, $remember);
if (!$error) {
return redirect()->intended()
->withSuccess(trans('user::messages.successfully logged in'));
}
return redirect()->back()->withInput()->withError($error);
}
public function getRegister()
{
return view('user::public.register');
}
public function postRegister(RegisterRequest $request)
{
app(UserRegistration::class)->register($request->all());
return redirect()->route('register')
->withSuccess(trans('user::messages.account created check email for activation'));
}
public function getLogout()
{
$this->auth->logout();
return redirect()->route('login');
}
public function getActivate($userId, $code)
{
if ($this->auth->activate($userId, $code)) {
return redirect()->route('login')
->withSuccess(trans('user::messages.account activated you can now login'));
}
return redirect()->route('register')
->withError(trans('user::messages.there was an error with the activation'));
}
public function getReset()
{
return view('user::public.reset.begin');
}
public function postReset(ResetRequest $request)
{
try {
app(UserResetter::class)->startReset($request->all());
} catch (UserNotFoundException $e) {
return redirect()->back()->withInput()
->withError(trans('user::messages.no user found'));
}
return redirect()->route('reset')
->withSuccess(trans('user::messages.check email to reset password'));
}
public function getResetComplete()
{
return view('user::public.reset.complete');
}
public function postResetComplete($userId, $code, ResetCompleteRequest $request)
{
try {
app(UserResetter::class)->finishReset(
array_merge($request->all(), ['userId' => $userId, 'code' => $code])
);
} catch (UserNotFoundException $e) {
return redirect()->back()->withInput()
->withError(trans('user::messages.user no longer exists'));
} catch (InvalidOrExpiredResetCode $e) {
return redirect()->back()->withInput()
->withError(trans('user::messages.invalid reset code'));
}
return redirect()->route('login')
->withSuccess(trans('user::messages.password reset'));
}
}
<?php
namespace Modules\User\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Modules\User\Repositories\UserTokenRepository;
class AuthorisedApiToken
{
/**
* @var UserTokenRepository
*/
private $userToken;
public function __construct(UserTokenRepository $userToken)
{
$this->userToken = $userToken;
}
public function handle(Request $request, \Closure $next)
{
if ($request->header('Authorization') === null) {
return new Response('Forbidden', 403);
}
if ($this->isValidToken($request->header('Authorization')) === false) {
return new Response('Forbidden', 403);
}
return $next($request);
}
private function isValidToken($token)
{
$found = $this->userToken->findByAttributes(['access_token' => $this->parseToken($token)]);
if ($found === null) {
return false;
}
return true;
}
private function parseToken($token)
{
return str_replace('Bearer ', '', $token);
}
}
<?php
namespace Modules\User\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Modules\User\Repositories\UserTokenRepository;
class AuthorisedApiTokenAdmin
{
/**
* @var UserTokenRepository
*/
private $userToken;
public function __construct(UserTokenRepository $userToken)
{
$this->userToken = $userToken;
}
public function handle(Request $request, \Closure $next)
{
if ($request->header('Authorization') === null) {
return new Response('Forbidden', 403);
}
if ($this->isValidToken($request->header('Authorization')) === false) {
return new Response('Forbidden', 403);
}
return $next($request);
}
private function isValidToken($token)
{
$found = $this->userToken->findByAttributes(['access_token' => $this->parseToken($token)]);
if ($found === null) {
return false;
}
if ($found->user->hasRoleName('admin') === false) {
return false;
}
return true;
}
private function parseToken($token)
{
return str_replace('Bearer ', '', $token);
}
}
<?php
namespace Modules\User\Http\Middleware;
use Illuminate\Support\Facades\Redirect;
use Modules\User\Contracts\Authentication;
class GuestMiddleware
{
/**
* @var Authentication
*/
private $auth;
public function __construct(Authentication $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next)
{
if ($this->auth->check()) {
return Redirect::route(config('asgard.user.config.redirect_route_after_login'));
}
return $next($request);
}
}
<?php
namespace Modules\User\Http\Middleware;
use Modules\User\Contracts\Authentication;
/**
* Class LoggedInMiddleware
* @package Modules\User\Http\Middleware
* Middleware to make sure affected routes need a logged in user
*/
class LoggedInMiddleware
{
/**
* @var Authentication
*/
private $auth;
public function __construct(Authentication $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next)
{
if ($this->auth->check() === false) {
return redirect()->guest(config('asgard.user.config.redirect_route_not_logged_in', 'auth/login'));
}
return $next($request);
}
}
<?php
namespace Modules\User\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Modules\User\Contracts\Authentication;
use Modules\User\Entities\UserInterface;
use Modules\User\Repositories\UserTokenRepository;
class TokenCan
{
/**
* @var UserTokenRepository
*/
private $userToken;
/**
* @var Authentication
*/
private $auth;
public function __construct(UserTokenRepository $userToken, Authentication $auth)
{
$this->userToken = $userToken;
$this->auth = $auth;
}
/**
* @param Request $request
* @param \Closure $next
* @param string $permission
* @return Response
*/
public function handle(Request $request, \Closure $next, $permission)
{
if ($request->header('Authorization') === null) {
return new Response('Forbidden', Response::HTTP_FORBIDDEN);
}
$user = $this->getUserFromToken($request->header('Authorization'));
if ($user->hasAccess($permission) === false) {
return response('Unauthorized.', Response::HTTP_UNAUTHORIZED);
}
return $next($request);
}
/**
* @param string $token
* @return UserInterface
*/
private function getUserFromToken($token)
{
$token = $this->userToken->findByAttributes(['access_token' => $this->parseToken($token)]);
return $token->user;
}
/**
* @param string $token
* @return string
*/
private function parseToken($token)
{
return str_replace('Bearer ', '', $token);
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateUserRequest extends FormRequest
{
public function rules()
{
return [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|unique:users|email',
'password' => 'required|min:3|confirmed',
];
}
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class LoginRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required',
'password' => 'required',
];
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email|unique:users',
'password' => 'required|confirmed|min:3',
];
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ResetCompleteRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'password' => 'required|min:3|confirmed',
'password_confirmation' => 'required',
];
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ResetRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email',
];
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RolesRequest extends FormRequest
{
public function rules()
{
return [
'name' => 'required',
];
}
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
namespace Modules\User\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UpdateUserRequest extends FormRequest
{
public function rules()
{
$userId = $this->route()->getParameter('users');
return [
'email' => "required|email|unique:users,email,{$userId}",
'first_name' => 'required',
'last_name' => 'required',
'password' => 'confirmed',
];
}
public function authorize()
{
return true;
}
public function messages()
{
return [];
}
}
<?php
use Illuminate\Routing\Router;
/** @var Router $router */
$router->group(['prefix' => '/user'], function (Router $router) {
$router->get('users', [
'as' => 'admin.user.user.index',
'uses' => 'UserController@index',
'middleware' => 'can:user.users.index',
]);
$router->get('users/create', [
'as' => 'admin.user.user.create',
'uses' => 'UserController@create',
'middleware' => 'can:user.users.create',
]);
$router->post('users', [
'as' => 'admin.user.user.store',
'uses' => 'UserController@store',
'middleware' => 'can:user.users.create',
]);
$router->get('users/{users}/edit', [
'as' => 'admin.user.user.edit',
'uses' => 'UserController@edit',
'middleware' => 'can:user.users.edit',
]);
$router->put('users/{users}/edit', [
'as' => 'admin.user.user.update',
'uses' => 'UserController@update',
'middleware' => 'can:user.users.edit',
]);
$router->get('users/{users}/sendResetPassword', [
'as' => 'admin.user.user.sendResetPassword',
'uses' => 'UserController@sendResetPassword',
'middleware' => 'can:user.users.edit',
]);
$router->delete('users/{users}', [
'as' => 'admin.user.user.destroy',
'uses' => 'UserController@destroy',
'middleware' => 'can:user.users.destroy',
]);
$router->get('roles', [
'as' => 'admin.user.role.index',
'uses' => 'RolesController@index',
'middleware' => 'can:user.roles.index',
]);
$router->get('roles/create', [
'as' => 'admin.user.role.create',
'uses' => 'RolesController@create',
'middleware' => 'can:user.roles.create',
]);
$router->post('roles', [
'as' => 'admin.user.role.store',
'uses' => 'RolesController@store',
'middleware' => 'can:user.roles.create',
]);
$router->get('roles/{roles}/edit', [
'as' => 'admin.user.role.edit',
'uses' => 'RolesController@edit',
'middleware' => 'can:user.roles.edit',
]);
$router->put('roles/{roles}/edit', [
'as' => 'admin.user.role.update',
'uses' => 'RolesController@update',
'middleware' => 'can:user.roles.edit',
]);
$router->delete('roles/{roles}', [
'as' => 'admin.user.role.destroy',
'uses' => 'RolesController@destroy',
'middleware' => 'can:user.roles.destroy',
]);
});
$router->group(['prefix' => '/account'], function (Router $router) {
$router->bind('userTokenId', function ($id) {
return app(\Modules\User\Repositories\UserTokenRepository::class)->find($id);
});
$router->get('api-keys', [
'as' => 'admin.account.api.index',
'uses' => 'Account\ApiKeysController@index',
'middleware' => 'can:account.api-keys.index',
]);
$router->get('api-keys/create', [
'as' => 'admin.account.api.create',
'uses' => 'Account\ApiKeysController@create',
'middleware' => 'can:account.api-keys.create',
]);
$router->delete('api-keys/{userTokenId}', [
'as' => 'admin.account.api.destroy',
'uses' => 'Account\ApiKeysController@destroy',
'middleware' => 'can:account.api-keys.destroy',
]);
});
<?php
use Illuminate\Routing\Router;
/** @var Router $router */
$router->group(['prefix' => 'auth'], function (Router $router) {
# Login
$router->get('login', ['middleware' => 'auth.guest', 'as' => 'login', 'uses' => 'AuthController@getLogin']);
$router->post('login', ['as' => 'login.post', 'uses' => 'AuthController@postLogin']);
# Register
if (config('asgard.user.config.allow_user_registration', true)) {
$router->get('register', ['middleware' => 'auth.guest', 'as' => 'register', 'uses' => 'AuthController@getRegister']);
$router->post('register', ['as' => 'register.post', 'uses' => 'AuthController@postRegister']);
}
# Account Activation
$router->get('activate/{userId}/{activationCode}', 'AuthController@getActivate');
# Reset password
$router->get('reset', ['as' => 'reset', 'uses' => 'AuthController@getReset']);
$router->post('reset', ['as' => 'reset.post', 'uses' => 'AuthController@postReset']);
$router->get('reset/{id}/{code}', ['as' => 'reset.complete', 'uses' => 'AuthController@getResetComplete']);
$router->post('reset/{id}/{code}', ['as' => 'reset.complete.post', 'uses' => 'AuthController@postResetComplete']);
# Logout
$router->get('logout', ['as' => 'logout', 'uses' => 'AuthController@getLogout']);
});
# License (MIT)
Copyright (c) 2016 Nicolas Widart , n.widart@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<?php
namespace Modules\User\Permissions;
use Nwidart\Modules\Module;
class PermissionManager
{
/**
* @var Module
*/
private $module;
/**
*/
public function __construct()
{
$this->module = app('modules');
}
/**
* Get the permissions from all the enabled modules
* @return array
*/
public function all()
{
$permissions = [];
foreach ($this->module->enabled() as $enabledModule) {
$configuration = config(strtolower('asgard.' . $enabledModule->getName()) . '.permissions');
if ($configuration) {
$permissions[$enabledModule->getName()] = $configuration;
}
}
return $permissions;
}
/**
* Return a correctly type casted permissions array
* @param $permissions
* @return array
*/
public function clean($permissions)
{
if (!$permissions) {
return [];
}
$cleanedPermissions = [];
foreach ($permissions as $permissionName => $checkedPermission) {
if ($this->getState($checkedPermission) !== null) {
$cleanedPermissions[$permissionName] = $this->getState($checkedPermission);
}
}
return $cleanedPermissions;
}
/**
* @param $checkedPermission
* @return bool
*/
protected function getState($checkedPermission)
{
if ($checkedPermission === '1') {
return true;
}
if ($checkedPermission === '-1') {
return false;
}
return null;
}
/**
* Are all of the permissions passed of false value?
* @param array $permissions Permissions array
* @return bool
*/
public function permissionsAreAllFalse(array $permissions)
{
$uniquePermissions = array_unique($permissions);
if (count($uniquePermissions) > 1) {
return false;
}
$uniquePermission = reset($uniquePermissions);
$cleanedPermission = $this->getState($uniquePermission);
return $cleanedPermission === false;
}
}
<?php
namespace Modules\User\Presenters;
use Laracasts\Presenter\Presenter;
class UserPresenter extends Presenter
{
/**
* Return the gravatar link for the users email
* @param int $size
* @return string
*/
public function gravatar($size = 90)
{
$email = md5($this->email);
return "//www.gravatar.com/avatar/$email?s=$size";
}
/**
* @return string
*/
public function fullname()
{
return $this->name ?: $this->first_name . ' ' . $this->last_name;
}
}
<?php
namespace Modules\User\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Maatwebsite\Sidebar\Domain\Events\FlushesSidebarCache;
use Modules\User\Events\Handlers\SendRegistrationConfirmationEmail;
use Modules\User\Events\Handlers\SendResetCodeEmail;
use Modules\User\Events\RoleWasUpdated;
use Modules\User\Events\UserHasBegunResetProcess;
use Modules\User\Events\UserHasRegistered;
use Modules\User\Events\UserWasUpdated;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
UserHasRegistered::class => [
SendRegistrationConfirmationEmail::class,
],
UserHasBegunResetProcess::class => [
SendResetCodeEmail::class,
],
UserWasUpdated::class => [
FlushesSidebarCache::class,
],
RoleWasUpdated::class => [
FlushesSidebarCache::class,
],
];
}
<?php
namespace Modules\User\Providers;
use Modules\Core\Providers\RoutingServiceProvider as CoreRoutingServiceProvider;
class RouteServiceProvider extends CoreRoutingServiceProvider
{
/**
* The root namespace to assume when generating URLs to actions.
*
* @var string
*/
protected $namespace = 'Modules\User\Http\Controllers';
/**
* @return string
*/
protected function getFrontendRoute()
{
return __DIR__ . '/../Http/frontendRoutes.php';
}
/**
* @return string
*/
protected function getBackendRoute()
{
return __DIR__ . '/../Http/backendRoutes.php';
}
/**
* @return string
*/
protected function getApiRoute()
{
return false;
}
}
<?php
namespace Modules\User\Providers;
use Cartalyst\Sentinel\Laravel\SentinelServiceProvider;
use Illuminate\Support\ServiceProvider;
use Modules\Core\Traits\CanPublishConfiguration;
use Modules\User\Contracts\Authentication;
use Modules\User\Entities\UserToken;
use Modules\User\Http\Middleware\AuthorisedApiToken;
use Modules\User\Http\Middleware\AuthorisedApiTokenAdmin;
use Modules\User\Http\Middleware\GuestMiddleware;
use Modules\User\Http\Middleware\LoggedInMiddleware;
use Modules\User\Http\Middleware\TokenCan;
use Modules\User\Repositories\Cache\CacheUserTokenDecorator;
use Modules\User\Repositories\Eloquent\EloquentUserTokenRepository;
use Modules\User\Repositories\RoleRepository;
use Modules\User\Repositories\UserRepository;
use Modules\User\Repositories\UserTokenRepository;
class UserServiceProvider extends ServiceProvider
{
use CanPublishConfiguration;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* @var array
*/
protected $providers = [
'Sentinel' => SentinelServiceProvider::class,
];
/**
* @var array
*/
protected $middleware = [
'auth.guest' => GuestMiddleware::class,
'logged.in' => LoggedInMiddleware::class,
'api.token' => AuthorisedApiToken::class,
'api.token.admin' => AuthorisedApiTokenAdmin::class,
'token-can' => TokenCan::class,
];
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->register($this->getUserPackageServiceProvider());
$this->registerBindings();
}
/**
*/
public function boot()
{
$this->registerMiddleware();
$this->publishes([
__DIR__ . '/../Resources/views' => base_path('resources/views/asgard/user'),
]);
$this->loadViewsFrom(base_path('resources/views/asgard/user'), 'user');
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'user');
$this->publishConfig('user', 'permissions');
$this->publishConfig('user', 'config');
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array();
}
private function registerBindings()
{
$driver = config('asgard.user.config.driver', 'Sentinel');
$this->app->bind(
UserRepository::class,
"Modules\\User\\Repositories\\{$driver}\\{$driver}UserRepository"
);
$this->app->bind(
RoleRepository::class,
"Modules\\User\\Repositories\\{$driver}\\{$driver}RoleRepository"
);
$this->app->bind(
Authentication::class,
"Modules\\User\\Repositories\\{$driver}\\{$driver}Authentication"
);
$this->app->bind(UserTokenRepository::class, function () {
$repository = new EloquentUserTokenRepository(new UserToken());
if (! config('app.cache')) {
return $repository;
}
return new CacheUserTokenDecorator($repository);
});
}
private function registerMiddleware()
{
foreach ($this->middleware as $name => $class) {
$this->app['router']->middleware($name, $class);
}
}
private function getUserPackageServiceProvider()
{
$driver = config('asgard.user.config.driver', 'Sentinel');
if (!isset($this->providers[$driver])) {
throw new \Exception("Driver [{$driver}] does not exist");
}
return $this->providers[$driver];
}
}
<?php
namespace Modules\User\Repositories\Cache;
use Modules\Core\Repositories\Cache\BaseCacheDecorator;
use Modules\User\Repositories\UserTokenRepository;
class CacheUserTokenDecorator extends BaseCacheDecorator implements UserTokenRepository
{
/**
* @var UserTokenRepository
*/
protected $repository;
public function __construct(UserTokenRepository $repository)
{
parent::__construct();
$this->entityName = 'user-tokens';
$this->repository = $repository;
}
/**
* Get all tokens for the given user
* @param int $userId
* @return \Illuminate\Database\Eloquent\Collection
*/
public function allForUser($userId)
{
return $this->cache
->tags([$this->entityName, 'global'])
->remember("{$this->locale}.{$this->entityName}.allForUser.{$userId}", $this->cacheTime,
function () use ($userId) {
return $this->repository->allForUser($userId);
}
);
}
/**
* @param int $userId
* @return \Modules\User\Entities\UserToken
*/
public function generateFor($userId)
{
$this->clearCache();
return $this->repository->generateFor($userId);
}
}
<?php
namespace Modules\User\Repositories\Eloquent;
use Illuminate\Database\QueryException;
use Modules\Core\Repositories\Eloquent\EloquentBaseRepository;
use Modules\User\Repositories\UserTokenRepository;
use Ramsey\Uuid\Uuid;
class EloquentUserTokenRepository extends EloquentBaseRepository implements UserTokenRepository
{
/**
* Get all tokens for the given user
* @param int $userId
* @return \Illuminate\Database\Eloquent\Collection
*/
public function allForUser($userId)
{
return $this->model->where('user_id', $userId)->get();
}
/**
* @param int $userId
* @return \Modules\User\Entities\UserToken
*/
public function generateFor($userId)
{
try {
$uuid4 = Uuid::uuid4();
$userToken = $this->model->create(['user_id' => $userId, 'access_token' => $uuid4]);
} catch (QueryException $e) {
$this->generateFor($userId);
}
return $userToken;
}
}
<?php
namespace Modules\User\Repositories;
/**
* Interface RoleRepository
* @package Modules\User\Repositories
*/
interface RoleRepository
{
/**
* Return all the roles
* @return mixed
*/
public function all();
/**
* Create a role resource
* @return mixed
*/
public function create($data);
/**
* Find a role by its id
* @param $id
* @return mixed
*/
public function find($id);
/**
* Update a role
* @param $id
* @param $data
* @return mixed
*/
public function update($id, $data);
/**
* Delete a role
* @param $id
* @return mixed
*/
public function delete($id);
/**
* Find a role by its name
* @param string $name
* @return mixed
*/
public function findByName($name);
}
<?php
namespace Modules\User\Repositories\Sentinel;
use Cartalyst\Sentinel\Checkpoints\NotActivatedException;
use Cartalyst\Sentinel\Checkpoints\ThrottlingException;
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Cartalyst\Sentinel\Laravel\Facades\Reminder;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Modules\User\Contracts\Authentication;
use Modules\User\Events\UserHasActivatedAccount;
class SentinelAuthentication implements Authentication
{
/**
* Authenticate a user
* @param array $credentials
* @param bool $remember Remember the user
* @return mixed
*/
public function login(array $credentials, $remember = false)
{
try {
if (Sentinel::authenticate($credentials, $remember)) {
return false;
}
return trans('user::users.invalid login or password');
} catch (NotActivatedException $e) {
return trans('user::users.account not validated');
} catch (ThrottlingException $e) {
$delay = $e->getDelay();
return trans('user::users.account is blocked', ['delay' => $delay]);
}
}
/**
* Register a new user.
* @param array $user
* @return bool
*/
public function register(array $user)
{
return Sentinel::getUserRepository()->create((array) $user);
}
/**
* Assign a role to the given user.
* @param \Modules\User\Repositories\UserRepository $user
* @param \Modules\User\Repositories\RoleRepository $role
* @return mixed
*/
public function assignRole($user, $role)
{
return $role->users()->attach($user);
}
/**
* Log the user out of the application.
* @return bool
*/
public function logout()
{
return Sentinel::logout();
}
/**
* Activate the given used id
* @param int $userId
* @param string $code
* @return mixed
*/
public function activate($userId, $code)
{
$user = Sentinel::findById($userId);
$success = Activation::complete($user, $code);
if ($success) {
event(new UserHasActivatedAccount($user));
}
return $success;
}
/**
* Create an activation code for the given user
* @param \Modules\User\Repositories\UserRepository $user
* @return mixed
*/
public function createActivation($user)
{
return Activation::create($user)->code;
}
/**
* Create a reminders code for the given user
* @param \Modules\User\Repositories\UserRepository $user
* @return mixed
*/
public function createReminderCode($user)
{
$reminder = Reminder::exists($user) ?: Reminder::create($user);
return $reminder->code;
}
/**
* Completes the reset password process
* @param $user
* @param string $code
* @param string $password
* @return bool
*/
public function completeResetPassword($user, $code, $password)
{
return Reminder::complete($user, $code, $password);
}
/**
* Determines if the current user has access to given permission
* @param $permission
* @return bool
*/
public function hasAccess($permission)
{
if (! Sentinel::check()) {
return false;
}
return Sentinel::hasAccess($permission);
}
/**
* Check if the user is logged in
* @return bool
*/
public function check()
{
$user = Sentinel::check();
if ($user) {
return true;
}
return false;
}
/**
* Get the currently logged in user
* @return \Modules\User\Entities\UserInterface
*/
public function user()
{
return Sentinel::check();
}
/**
* Get the ID for the currently authenticated user
* @return int
*/
public function id()
{
$user = $this->user();
if ($user === null) {
return 0;
}
return $user->id;
}
}
<?php
namespace Modules\User\Repositories\Sentinel;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Modules\User\Events\RoleWasUpdated;
use Modules\User\Repositories\RoleRepository;
class SentinelRoleRepository implements RoleRepository
{
/**
* @var \Cartalyst\Sentinel\Roles\EloquentRole
*/
protected $role;
public function __construct()
{
$this->role = Sentinel::getRoleRepository()->createModel();
}
/**
* Return all the roles
* @return mixed
*/
public function all()
{
return $this->role->all();
}
/**
* Create a role resource
* @return mixed
*/
public function create($data)
{
$this->role->create($data);
}
/**
* Find a role by its id
* @param $id
* @return mixed
*/
public function find($id)
{
return $this->role->find($id);
}
/**
* Update a role
* @param $id
* @param $data
* @return mixed
*/
public function update($id, $data)
{
$role = $this->role->find($id);
$role->fill($data);
$role->save();
event(new RoleWasUpdated($role));
}
/**
* Delete a role
* @param $id
* @return mixed
*/
public function delete($id)
{
$role = $this->role->find($id);
return $role->delete();
}
/**
* Find a role by its name
* @param string $name
* @return mixed
*/
public function findByName($name)
{
return Sentinel::findRoleByName($name);
}
}
<?php
namespace Modules\User\Repositories\Sentinel;
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Illuminate\Support\Facades\Hash;
use Modules\User\Entities\Sentinel\User;
use Modules\User\Events\UserHasRegistered;
use Modules\User\Events\UserWasUpdated;
use Modules\User\Exceptions\UserNotFoundException;
use Modules\User\Repositories\UserRepository;
class SentinelUserRepository implements UserRepository
{
/**
* @var \Modules\User\Entities\Sentinel\User
*/
protected $user;
/**
* @var \Cartalyst\Sentinel\Roles\EloquentRole
*/
protected $role;
public function __construct()
{
$this->user = Sentinel::getUserRepository()->createModel();
$this->role = Sentinel::getRoleRepository()->createModel();
}
/**
* Returns all the users
* @return object
*/
public function all()
{
return $this->user->all();
}
/**
* Create a user resource
* @param $data
* @return mixed
*/
public function create(array $data)
{
$user = $this->user->create((array) $data);
event(new UserHasRegistered($user));
return $user;
}
/**
* Create a user and assign roles to it
* @param array $data
* @param array $roles
* @param bool $activated
*/
public function createWithRoles($data, $roles, $activated = false)
{
$this->hashPassword($data);
$user = $this->create((array) $data);
if (!empty($roles)) {
$user->roles()->attach($roles);
}
if ($activated) {
$activation = Activation::create($user);
Activation::complete($user, $activation->code);
}
}
/**
* Create a user and assign roles to it
* But don't fire the user created event
* @param array $data
* @param array $roles
* @param bool $activated
* @return User
*/
public function createWithRolesFromCli($data, $roles, $activated = false)
{
$this->hashPassword($data);
$user = $this->user->create((array) $data);
if (!empty($roles)) {
$user->roles()->attach($roles);
}
if ($activated) {
$activation = Activation::create($user);
Activation::complete($user, $activation->code);
}
return $user;
}
/**
* Find a user by its ID
* @param $id
* @return mixed
*/
public function find($id)
{
return $this->user->find($id);
}
/**
* Update a user
* @param $user
* @param $data
* @return mixed
*/
public function update($user, $data)
{
$user = $user->update($data);
event(new UserWasUpdated($user));
return $user;
}
/**
* @param $userId
* @param $data
* @param $roles
* @internal param $user
* @return mixed
*/
public function updateAndSyncRoles($userId, $data, $roles)
{
$user = $this->user->find($userId);
$this->checkForNewPassword($data);
$this->checkForManualActivation($user, $data);
$user = $user->fill($data);
$user->save();
event(new UserWasUpdated($user));
if (!empty($roles)) {
$user->roles()->sync($roles);
}
}
/**
* Deletes a user
* @param $id
* @throws UserNotFoundException
* @return mixed
*/
public function delete($id)
{
if ($user = $this->user->find($id)) {
return $user->delete();
};
throw new UserNotFoundException();
}
/**
* Find a user by its credentials
* @param array $credentials
* @return mixed
*/
public function findByCredentials(array $credentials)
{
return Sentinel::findByCredentials($credentials);
}
/**
* Hash the password key
* @param array $data
*/
private function hashPassword(array &$data)
{
$data['password'] = Hash::make($data['password']);
}
/**
* Check if there is a new password given
* If not, unset the password field
* @param array $data
*/
private function checkForNewPassword(array &$data)
{
if (! $data['password']) {
unset($data['password']);
return;
}
$data['password'] = Hash::make($data['password']);
}
/**
* Check and manually activate or remove activation for the user
* @param $user
* @param array $data
*/
private function checkForManualActivation($user, array &$data)
{
if (Activation::completed($user) && !$data['activated']) {
return Activation::remove($user);
}
if (!Activation::completed($user) && $data['activated']) {
$activation = Activation::create($user);
return Activation::complete($user, $activation->code);
}
}
}
<?php
namespace Modules\User\Repositories;
use Modules\User\Entities\UserInterface;
/**
* Interface UserRepository
* @package Modules\User\Repositories
*/
interface UserRepository
{
/**
* Returns all the users
* @return object
*/
public function all();
/**
* Create a user resource
* @param array $data
* @return mixed
*/
public function create(array $data);
/**
* Create a user and assign roles to it
* @param array $data
* @param array $roles
* @param bool $activated
*/
public function createWithRoles($data, $roles, $activated = false);
/**
* Create a user and assign roles to it
* But don't fire the user created event
* @param array $data
* @param array $roles
* @param bool $activated
* @return UserInterface
*/
public function createWithRolesFromCli($data, $roles, $activated = false);
/**
* Find a user by its ID
* @param $id
* @return mixed
*/
public function find($id);
/**
* Update a user
* @param $user
* @param $data
* @return mixed
*/
public function update($user, $data);
/**
* Update a user and sync its roles
* @param int $userId
* @param $data
* @param $roles
* @return mixed
*/
public function updateAndSyncRoles($userId, $data, $roles);
/**
* Deletes a user
* @param $id
* @return mixed
*/
public function delete($id);
/**
* Find a user by its credentials
* @param array $credentials
* @return mixed
*/
public function findByCredentials(array $credentials);
}
<?php
namespace Modules\User\Repositories;
use Modules\Core\Repositories\BaseRepository;
interface UserTokenRepository extends BaseRepository
{
/**
* Get all tokens for the given user
* @param int $userId
* @return \Illuminate\Database\Eloquent\Collection
*/
public function allForUser($userId);
/**
* @param int $userId
* @return \Modules\User\Entities\UserToken
*/
public function generateFor($userId);
}
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::users.api-keys') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class="active">{{ trans('user::users.api-keys') }}</li>
</ol>
@stop
@section('content')
<div class="row">
<div class="col-xs-12">
<div class="row">
<div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
<a href="{{ route('admin.account.api.create') }}" class="btn btn-primary btn-flat">
<i class="fa fa-plus"></i> {{ trans('user::users.generate new api key') }}
</a>
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ trans('user::users.your api keys') }}</h3>
</div>
<div class="box-body">
<div class="col-md-4">
<?php if ($tokens->isEmpty() === false): ?>
<ul class="list-unstyled">
<?php foreach ($tokens as $token): ?>
<li style="margin-bottom: 20px;">
{!! Form::open(['route' => ['admin.account.api.destroy', $token->id], 'method' => 'delete', 'class' => '']) !!}
<div class="input-group input-group-sm">
<span class="input-group-btn">
<button type="submit" class="btn btn-danger btn-flat" onclick="return confirm('{{ trans('user::users.delete api key confirm') }}')">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</span>
<input type="text" class="form-control api-key" readonly value="{{ $token->access_token }}" >
<span class="input-group-btn">
<a href="#" class="btn btn-default btn-flat jsClipboardButton">
<i class="fa fa-clipboard" aria-hidden="true"></i>
</a>
</span>
</div>
{!! Form::close() !!}
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>{{ trans('user::users.you have no api keys') }} <a href="{{ route('admin.account.api.create') }}">{{ trans('user::users.generate one') }}</a></p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<!-- /.col (MAIN) -->
</div>
@include('core::partials.delete-modal')
@stop
@section('scripts')
<script>
new Clipboard('.jsClipboardButton', {
target: function(trigger) {
return $(trigger).parent().parent().find('.api-key')[0];
}
});
</script>
@stop
<div class="row permission">
<div class="col-sm-3">
<div class="visible-sm-block visible-md-block visible-lg-block">
<label class="control-label text-right" style="display: block">{{ trans($permissionLabel) }}</label>
</div>
<div class="visible-xs-block">
<label class="control-label">{{ trans($permissionLabel) }}</label>
</div>
</div>
<div class="col-sm-9">
<?php if (isset($model)): ?>
<?php $current = current_permission_value($model, $subPermissionTitle, $permissionAction); ?>
<?php endif; ?>
<label class="radio-inline" for="{{ $subPermissionTitle. '.' . $permissionAction }}_allow">
<input type="radio" value="1" id="{{ $subPermissionTitle. '.' . $permissionAction }}_allow" name="permissions[{{ $subPermissionTitle. '.' . $permissionAction }}]"
{{ isset($current) && $current === 1 ? 'checked' : '' }} class="flat-blue jsAllow">
{{ trans('user::roles.allow') }}
</label>
<label class="radio-inline" for="{{ $subPermissionTitle. '.' . $permissionAction }}_deny">
<input type="radio" value="-1" id="{{ $subPermissionTitle. '.' . $permissionAction }}_deny" name="permissions[{{ $subPermissionTitle. '.' . $permissionAction }}]"
{{ isset($current) && $current === -1 ? 'checked' : '' }} class="flat-blue jsDeny">
{{ trans('user::roles.deny') }}
</label>
<label class="radio-inline" for="{{ $subPermissionTitle. '.' . $permissionAction }}_inherit">
<input type="radio" value="0" id="{{ $subPermissionTitle. '.' . $permissionAction }}_inherit" name="permissions[{{ $subPermissionTitle. '.' . $permissionAction }}]"
{{ isset($current) && $current === 0 ? 'checked' : '' }} {{ isset($current) === false ? 'checked' : '' }} class="flat-blue jsInherit">
{{ trans('user::roles.inherit') }}
</label>
</div>
</div>
<style>
h3 {
border-bottom: 1px solid #eee;
}
.permission {
padding: 6px 0 4px 0;
}
</style>
<div class="box-body">
<div class="row">
<div class="col-md-12">
<?php foreach ($permissions as $name => $value): ?>
<div class="row">
<div class="col-md-12">
<h3>{{ ucfirst($name) }}</h3>
</div>
</div>
<?php foreach ($value as $subPermissionTitle => $permissionActions): ?>
<div class="permissionGroup">
<div class="row">
<div class="col-md-6">
<h4 class="pull-left">{{ ucfirst($subPermissionTitle) }}</h4>
<p class="pull-right" style="margin-top: 10px;">
<a href="" class="jsSelectAllAllow">{{ trans('user::roles.allow all')}}</a> |
<a href="" class="jsSelectAllDeny">{{ trans('user::roles.deny all')}}</a> |
<a href="" class="jsSelectAllInherit">{{ trans('user::roles.inherit all')}}</a>
</p>
</div>
</div>
<div class="row">
<?php foreach ($permissionActions as $permissionAction => $permissionLabel): ?>
<div class="col-md-12">
@include('user::admin.partials.permission-part')
</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
</div>
</div>
@include('user::admin.partials.permissions-script')
<script>
$( document ).ready(function() {
$('.jsSelectAllAllow').on('click',function (event) {
event.preventDefault();
$(this).closest('.permissionGroup').find('.jsAllow').each(function (index, value) {
$(value).iCheck('check');
});
});
$('.jsSelectAllDeny').on('click',function (event) {
event.preventDefault();
$(this).closest('.permissionGroup').find('.jsDeny').each(function (index, value) {
$(value).iCheck('check');
});
});
$('.jsSelectAllInherit').on('click',function (event) {
event.preventDefault();
$(this).closest('.permissionGroup').find('.jsInherit').each(function (index, value) {
$(value).iCheck('check');
});
});
});
</script>
<style>
h3 {
border-bottom: 1px solid #eee;
}
.permission {
padding: 6px 0 4px 0;
}
</style>
<div class="box-body">
<div class="row">
<div class="col-md-12">
<?php foreach ($permissions as $name => $value): ?>
<div class="row">
<div class="col-md-12">
<h3>{{ ucfirst($name) }}</h3>
</div>
</div>
<?php foreach ($value as $subPermissionTitle => $permissionActions): ?>
<div class="permissionGroup">
<div class="row">
<div class="col-md-6">
<h4 class="pull-left">{{ ucfirst($subPermissionTitle) }}</h4>
<p class="pull-right" style="margin-top: 10px;">
<a href="" class="jsSelectAllAllow">{{ trans('user::roles.allow all')}}</a> |
<a href="" class="jsSelectAllDeny">{{ trans('user::roles.deny all')}}</a> |
<a href="" class="jsSelectAllInherit">{{ trans('user::roles.inherit all')}}</a>
</p>
</div>
</div>
<div class="row">
<?php foreach ($permissionActions as $permissionAction => $permissionLabel): ?>
<div class="col-md-12">
@include('user::admin.partials.permission-part')
</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
</div>
</div>
@include('user::admin.partials.permissions-script')
@extends('layouts.master')
@section('content-header')
<h1>New Role</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class=""><a href="{{ URL::route('admin.user.role.index') }}">{{ trans('user::roles.breadcrumb.roles') }}</a></li>
<li class="active">{{ trans('user::roles.breadcrumb.new') }}</li>
</ol>
@stop
@section('content')
{!! Form::open(['route' => 'admin.user.role.store', 'method' => 'post']) !!}
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab_1-1" data-toggle="tab">{{ trans('user::roles.tabs.data') }}</a></li>
<li class=""><a href="#tab_2-2" data-toggle="tab">{{ trans('user::roles.tabs.permissions') }}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_1-1">
<div class="box-body">
<div class="row">
<div class="col-sm-6">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
{!! Form::label('name', trans('user::roles.form.name')) !!}
{!! Form::text('name', old('name'), ['class' => 'form-control', 'data-slug' => 'source', 'placeholder' => trans('user::roles.form.name')]) !!}
{!! $errors->first('name', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-6">
<div class="form-group{{ $errors->has('slug') ? ' has-error' : '' }}">
{!! Form::label('slug', trans('user::roles.form.slug')) !!}
{!! Form::text('slug', old('slug'), ['class' => 'form-control slug', 'data-slug' => 'target', 'placeholder' => trans('user::roles.form.slug')]) !!}
{!! $errors->first('slug', '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_2-2">
@include('user::admin.partials.permissions-create')
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat">{{ trans('user::button.create') }}</button>
<button class="btn btn-default btn-flat" name="button" type="reset">{{ trans('core::core.button.reset') }}</button>
<a class="btn btn-danger pull-right btn-flat" href="{{ URL::route('admin.user.role.index')}}"><i class="fa fa-times"></i> {{ trans('user::button.cancel') }}</a>
</div>
</div>
</div>
</div>
</div>
{!! Form::close() !!}
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('user::roles.navigation.back to index') }}</dd>
</dl>
@stop
@section('scripts')
<script>
$( document ).ready(function() {
$('input[type="checkbox"].flat-blue, input[type="radio"].flat-blue').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue'
});
$(document).keypressAction({
actions: [
{ key: 'b', route: "<?= route('admin.user.role.index') ?>" }
]
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::roles.title.edit') }} <small>{{ $role->name }}</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class=""><a href="{{ URL::route('admin.user.role.index') }}">{{ trans('user::roles.breadcrumb.roles') }}</a></li>
<li class="active">{{ trans('user::roles.breadcrumb.edit') }}</li>
</ol>
@stop
@section('content')
{!! Form::open(['route' => ['admin.user.role.update', $role->id], 'method' => 'put']) !!}
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab_1-1" data-toggle="tab">{{ trans('user::roles.tabs.data') }}</a></li>
<li class=""><a href="#tab_2-2" data-toggle="tab">{{ trans('user::roles.tabs.permissions') }}</a></li>
<li class=""><a href="#tab_3-3" data-toggle="tab">{{ trans('user::users.title.users') }}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_1-1">
<div class="box-body">
<div class="row">
<div class="col-sm-6">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
{!! Form::label('name', trans('user::roles.form.name')) !!}
{!! Form::text('name', old('name', $role->name), ['class' => 'form-control', 'data-slug' => 'source', 'placeholder' => trans('user::roles.form.name')]) !!}
{!! $errors->first('name', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-6">
<div class="form-group{{ $errors->has('slug') ? ' has-error' : '' }}">
{!! Form::label('slug', trans('user::roles.form.slug')) !!}
{!! Form::text('slug', old('slug', $role->slug), ['class' => 'form-control slug', 'data-slug' => 'target', 'placeholder' => trans('user::roles.form.slug')]) !!}
{!! $errors->first('slug', '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
</div>
</div><!-- /.tab-pane -->
<div class="tab-pane" id="tab_2-2">
@include('user::admin.partials.permissions', ['model' => $role])
</div><!-- /.tab-pane -->
<div class="tab-pane" id="tab_3-3">
<div class="box-body">
<div class="row">
<div class="col-md-12">
<h3>{{ trans('user::roles.title.users-with-roles') }}</h3>
<ul>
<?php foreach ($role->users as $user): ?>
<li>
<a href="{{ URL::route('admin.user.user.edit', [$user->id]) }}">{{ $user->present()->fullname() }}</a>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat">{{ trans('user::button.update') }}</button>
<button class="btn btn-default btn-flat" name="button" type="reset">{{ trans('core::core.button.reset') }}</button>
<a class="btn btn-danger pull-right btn-flat" href="{{ URL::route('admin.user.role.index')}}"><i class="fa fa-times"></i> {{ trans('user::button.cancel') }}</a>
</div>
</div><!-- /.tab-content -->
</div>
</div>
</div>
{!! Form::close() !!}
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('user::roles.navigation.back to index') }}</dd>
</dl>
@stop
@section('scripts')
<script>
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'b', route: "<?= route('admin.user.role.index') ?>" }
]
});
$('input[type="checkbox"].flat-blue, input[type="radio"].flat-blue').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue'
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::roles.title.roles') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class="active">{{ trans('user::roles.breadcrumb.roles') }}</li>
</ol>
@stop
@section('content')
<div class="row">
<div class="col-xs-12">
<div class="row">
<div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
<a href="{{ URL::route('admin.user.role.create') }}" class="btn btn-primary btn-flat" style="padding: 4px 10px;">
<i class="fa fa-pencil"></i> {{ trans('user::roles.button.new-role') }}
</a>
</div>
</div>
<div class="box box box-primary">
<div class="box-header">
</div>
<!-- /.box-header -->
<div class="box-body">
<table class="data-table table table-bordered table-hover">
<thead>
<tr>
<td>Id</td>
<th>{{ trans('user::roles.table.name') }}</th>
<th>{{ trans('user::users.table.created-at') }}</th>
<th data-sortable="false">{{ trans('user::users.table.actions') }}</th>
</tr>
</thead>
<tbody>
<?php if (isset($roles)): ?>
<?php foreach ($roles as $role): ?>
<tr>
<td>
<a href="{{ URL::route('admin.user.role.edit', [$role->id]) }}">
{{ $role->id }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.user.role.edit', [$role->id]) }}">
{{ $role->name }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.user.role.edit', [$role->id]) }}">
{{ $role->created_at }}
</a>
</td>
<td>
<div class="btn-group">
<a href="{{ route('admin.user.role.edit', [$role->id]) }}" class="btn btn-default btn-flat"><i class="fa fa-pencil"></i></a>
<button class="btn btn-danger btn-flat" data-toggle="modal" data-target="#modal-delete-confirmation" data-action-target="{{ route('admin.user.role.destroy', [$role->id]) }}"><i class="fa fa-trash"></i></button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
<tfoot>
<tr>
<td>Id</td>
<th>{{ trans('user::roles.table.name') }}</th>
<th>{{ trans('user::users.table.created-at') }}</th>
<th>{{ trans('user::users.table.actions') }}</th>
</tr>
</tfoot>
</table>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col (MAIN) -->
</div>
</div>
@include('core::partials.delete-modal')
@stop
@section('scripts')
<?php $locale = App::getLocale(); ?>
<script type="text/javascript">
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'c', route: "<?= route('admin.user.role.create') ?>" }
]
});
});
$(function () {
$('.data-table').dataTable({
"paginate": true,
"lengthChange": true,
"filter": true,
"sort": true,
"info": true,
"autoWidth": true,
"order": [[ 0, "desc" ]],
"language": {
"url": '<?php echo Module::asset("core:js/vendor/datatables/{$locale}.json") ?>'
}
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::users.title.new-user') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class=""><a href="{{ URL::route('admin.user.user.index') }}">{{ trans('user::users.breadcrumb.users') }}</a></li>
<li class="active">{{ trans('user::users.breadcrumb.new') }}</li>
</ol>
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('user::users.navigation.back to index') }}</dd>
</dl>
@stop
@section('content')
{!! Form::open(['route' => 'admin.user.user.store', 'method' => 'post']) !!}
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab_1-1" data-toggle="tab">{{ trans('user::users.tabs.data') }}</a></li>
<li class=""><a href="#tab_2-2" data-toggle="tab">{{ trans('user::users.tabs.roles') }}</a></li>
<li class=""><a href="#tab_3-3" data-toggle="tab">{{ trans('user::users.tabs.permissions') }}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_1-1">
<div class="box-body">
<div class="row">
<div class="col-sm-4">
<div class="form-group{{ $errors->has('first_name') ? ' has-error' : '' }}">
{!! Form::label('first_name', trans('user::users.form.first-name')) !!}
{!! Form::text('first_name', old('first_name'), ['class' => 'form-control', 'placeholder' => trans('user::users.form.first-name')]) !!}
{!! $errors->first('first_name', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-4">
<div class="form-group{{ $errors->has('last_name') ? ' has-error' : '' }}">
{!! Form::label('last_name', trans('user::users.form.last-name')) !!}
{!! Form::text('last_name', old('last_name'), ['class' => 'form-control', 'placeholder' => trans('user::users.form.last-name')]) !!}
{!! $errors->first('last_name', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-4">
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
{!! Form::label('email', trans('user::users.form.email')) !!}
{!! Form::email('email', old('email'), ['class' => 'form-control', 'placeholder' => trans('user::users.form.email')]) !!}
{!! $errors->first('email', '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
{!! Form::label('password', trans('user::users.form.password')) !!}
{!! Form::password('password', ['class' => 'form-control']) !!}
{!! $errors->first('password', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-6">
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
{!! Form::label('password_confirmation', trans('user::users.form.password-confirmation')) !!}
{!! Form::password('password_confirmation', ['class' => 'form-control']) !!}
{!! $errors->first('password_confirmation', '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_2-2">
<div class="box-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>{{ trans('user::users.tabs.roles') }}</label>
<select multiple="" class="form-control" name="roles[]">
<?php foreach ($roles as $role): ?>
<option value="{{ $role->id }}">{{ $role->name }}</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_3-3">
<div class="box-body">
@include('user::admin.partials.permissions-create')
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat">{{ trans('user::button.create') }}</button>
<button class="btn btn-default btn-flat" name="button" type="reset">{{ trans('core::core.button.reset') }}</button>
<a class="btn btn-danger pull-right btn-flat" href="{{ URL::route('admin.user.user.index')}}"><i class="fa fa-times"></i> {{ trans('user::button.cancel') }}</a>
</div>
</div>
</div>
</div>
</div>
{!! Form::close() !!}
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('user::users.navigation.back to index') }}</dd>
</dl>
@stop
@section('scripts')
<script>
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'b', route: "<?= route('admin.user.user.index') ?>" }
]
});
$('input[type="checkbox"].flat-blue, input[type="radio"].flat-blue').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue'
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::users.title.edit-user') }} <small>{{ $user->present()->fullname() }}</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class=""><a href="{{ URL::route('admin.user.user.index') }}">{{ trans('user::users.breadcrumb.users') }}</a></li>
<li class="active">{{ trans('user::users.breadcrumb.edit-user') }}</li>
</ol>
@stop
@section('content')
{!! Form::open(['route' => ['admin.user.user.update', $user->id], 'method' => 'put']) !!}
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab_1-1" data-toggle="tab">{{ trans('user::users.tabs.data') }}</a></li>
<li class=""><a href="#tab_2-2" data-toggle="tab">{{ trans('user::users.tabs.roles') }}</a></li>
<li class=""><a href="#tab_3-3" data-toggle="tab">{{ trans('user::users.tabs.permissions') }}</a></li>
<li class=""><a href="#password_tab" data-toggle="tab">{{ trans('user::users.tabs.new password') }}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_1-1">
<div class="box-body">
<div class="row">
<div class="col-sm-4">
<div class="form-group{{ $errors->has('first_name') ? ' has-error' : '' }}">
{!! Form::label('first_name', trans('user::users.form.first-name')) !!}
{!! Form::text('first_name', old('first_name', $user->first_name), ['class' => 'form-control', 'placeholder' => trans('user::users.form.first-name')]) !!}
{!! $errors->first('first_name', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-4">
<div class="form-group{{ $errors->has('last_name') ? ' has-error' : '' }}">
{!! Form::label('last_name', trans('user::users.form.last-name')) !!}
{!! Form::text('last_name', old('last_name', $user->last_name), ['class' => 'form-control', 'placeholder' => trans('user::users.form.last-name')]) !!}
{!! $errors->first('last_name', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-sm-4">
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
{!! Form::label('email', trans('user::users.form.email')) !!}
{!! Form::email('email', old('email', $user->email), ['class' => 'form-control', 'placeholder' => trans('user::users.form.email')]) !!}
{!! $errors->first('email', '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="checkbox{{ $errors->has('activated') ? ' has-error' : '' }}">
<input type="hidden" value="{{ $user->id === $currentUser->id ? '1' : '0' }}" name="activated"/>
<?php $oldValue = (bool) $user->isActivated() ? 'checked' : ''; ?>
<label for="activated">
<input id="activated"
name="activated"
type="checkbox"
class="flat-blue"
{{ $user->id === $currentUser->id ? 'disabled' : '' }}
{{ old('activated', $oldValue) }}
value="1" />
{{ trans('user::users.form.is activated') }}
{!! $errors->first('activated', '<span class="help-block">:message</span>') !!}
</label>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_2-2">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>{{ trans('user::users.tabs.roles') }}</label>
<select multiple="" class="form-control" name="roles[]">
<?php foreach ($roles as $role): ?>
<option value="{{ $role->id }}" <?php echo $user->hasRoleId($role->id) ? 'selected' : '' ?>>{{ $role->name }}</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_3-3">
<div class="box-body">
@include('user::admin.partials.permissions', ['model' => $user])
</div>
</div>
<div class="tab-pane" id="password_tab">
<div class="box-body">
<div class="row">
<div class="col-md-6">
<h4>{{ trans('user::users.new password setup') }}</h4>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
{!! Form::label('password', trans('user::users.form.new password')) !!}
{!! Form::input('password', 'password', '', ['class' => 'form-control']) !!}
{!! $errors->first('password', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
{!! Form::label('password_confirmation', trans('user::users.form.new password confirmation')) !!}
{!! Form::input('password', 'password_confirmation', '', ['class' => 'form-control']) !!}
{!! $errors->first('password_confirmation', '<span class="help-block">:message</span>') !!}
</div>
</div>
<div class="col-md-6">
<h4>{{ trans('user::users.tabs.or send reset password mail') }}</h4>
<a href="{{ route("admin.user.user.sendResetPassword", $user->id) }}" class="btn btn-flat bg-maroon">
{{ trans('user::users.send reset password email') }}
</a>
</div>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat">{{ trans('user::button.update') }}</button>
<button class="btn btn-default btn-flat" name="button" type="reset">{{ trans('core::core.button.reset') }}</button>
<a class="btn btn-danger pull-right btn-flat" href="{{ URL::route('admin.user.user.index')}}"><i class="fa fa-times"></i> {{ trans('user::button.cancel') }}</a>
</div>
</div>
</div>
</div>
</div>
{!! Form::close() !!}
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('user::users.navigation.back to index') }}</dd>
</dl>
@stop
@section('scripts')
<script>
$( document ).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
$(document).keypressAction({
actions: [
{ key: 'b', route: "<?= route('admin.user.role.index') ?>" }
]
});
$('input[type="checkbox"].flat-blue, input[type="radio"].flat-blue').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue'
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::users.title.users') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class="active">{{ trans('user::users.breadcrumb.users') }}</li>
</ol>
@stop
@section('content')
<div class="row">
<div class="col-xs-12">
<div class="row">
<div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
<a href="{{ URL::route('admin.user.user.create') }}" class="btn btn-primary btn-flat" style="padding: 4px 10px;">
<i class="fa fa-pencil"></i> {{ trans('user::users.button.new-user') }}
</a>
</div>
</div>
<div class="box box-primary">
<div class="box-header">
</div>
<!-- /.box-header -->
<div class="box-body">
<table class="data-table table table-bordered table-hover">
<thead>
<tr>
<th>Id</th>
<th>{{ trans('user::users.table.first-name') }}</th>
<th>{{ trans('user::users.table.last-name') }}</th>
<th>{{ trans('user::users.table.email') }}</th>
<th>{{ trans('user::users.table.created-at') }}</th>
<th data-sortable="false">{{ trans('user::users.table.actions') }}</th>
</tr>
</thead>
<tbody>
<?php if (isset($users)): ?>
<?php foreach ($users as $user): ?>
<tr>
<td>
<a href="{{ URL::route('admin.user.user.edit', [$user->id]) }}">
{{ $user->id }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.user.user.edit', [$user->id]) }}">
{{ $user->first_name }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.user.user.edit', [$user->id]) }}">
{{ $user->last_name }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.user.user.edit', [$user->id]) }}">
{{ $user->email }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.user.user.edit', [$user->id]) }}">
{{ $user->created_at }}
</a>
</td>
<td>
<div class="btn-group">
<a href="{{ route('admin.user.user.edit', [$user->id]) }}" class="btn btn-default btn-flat"><i class="fa fa-pencil"></i></a>
<?php if ($user->id != $currentUser->id): ?>
<button class="btn btn-danger btn-flat" data-toggle="modal" data-target="#modal-delete-confirmation" data-action-target="{{ route('admin.user.user.destroy', [$user->id]) }}"><i class="fa fa-trash"></i></button>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
<tfoot>
<tr>
<th>Id</th>
<th>{{ trans('user::users.table.first-name') }}</th>
<th>{{ trans('user::users.table.last-name') }}</th>
<th>{{ trans('user::users.table.email') }}</th>
<th>{{ trans('user::users.table.created-at') }}</th>
<th>{{ trans('user::users.table.actions') }}</th>
</tr>
</tfoot>
</table>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- /.col (MAIN) -->
</div>
</div>
@include('core::partials.delete-modal')
@stop
@section('scripts')
<?php $locale = App::getLocale(); ?>
<script type="text/javascript">
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'c', route: "<?= route('admin.user.user.create') ?>" }
]
});
});
$(function () {
$('.data-table').dataTable({
"paginate": true,
"lengthChange": true,
"filter": true,
"sort": true,
"info": true,
"autoWidth": true,
"order": [[ 0, "desc" ]],
"language": {
"url": '<?php echo Module::asset("core:js/vendor/datatables/{$locale}.json") ?>'
}
});
});
</script>
@stop
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>{{ trans('user::auth.reset password') }}</title>
<style type="text/css">
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6;
}
body {
background-color: #f6f6f6;
}
@media only screen and (max-width: 640px) {
h1 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h2 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h3 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h4 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h1 {
font-size: 22px !important;
}
h2 {
font-size: 18px !important;
}
h3 {
font-size: 16px !important;
}
.container {
width: 100% !important;
}
.content {
padding: 10px !important;
}
.content-wrapper {
padding: 10px !important;
}
.invoice {
width: 100% !important;
}
}
</style>
</head>
<body style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6; background: #f6f6f6; margin: 0; padding: 0;">
<table class="body-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background: #f6f6f6; margin: 0; padding: 0;">
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0;" valign="top"></td>
<td class="container" width="600" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;" valign="top">
<div class="content" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
<table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background: #fff; margin: 0; padding: 0; border: 1px solid #e9e9e9;">
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
<table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 20px; font-weight:bold; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
{{ trans('user::auth.reset password') }}
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
{{ trans('user::auth.to reset password complete this form') }} {{ URL::to("auth/reset/{$user['id']}/{$code}") }}.
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
<a href='{{ URL::to("auth/reset/{$user['id']}/{$code}") }}' class="btn-primary" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background: #348eda; margin: 0; padding: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">
{{ trans('user::auth.reset password') }}
</a>
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
&mdash; {{ trans('user::auth.end greeting') }}
</td>
</tr>
</table>
</td>
</tr>
</table>
<div class="footer" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
<table width="100%" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
</table>
</div></div>
</td>
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0;" valign="top"></td>
</tr>
</table>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>{{ trans('user::auth.welcome title') }}</title>
<style type="text/css">
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6;
}
body {
background-color: #f6f6f6;
}
@media only screen and (max-width: 640px) {
h1 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h2 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h3 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h4 {
font-weight: 600 !important; margin: 20px 0 5px !important;
}
h1 {
font-size: 22px !important;
}
h2 {
font-size: 18px !important;
}
h3 {
font-size: 16px !important;
}
.container {
width: 100% !important;
}
.content {
padding: 10px !important;
}
.content-wrapper {
padding: 10px !important;
}
.invoice {
width: 100% !important;
}
}
</style>
</head>
<body style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6; background: #f6f6f6; margin: 0; padding: 0;">
<table class="body-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background: #f6f6f6; margin: 0; padding: 0;">
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0;" valign="top"></td>
<td class="container" width="600" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;" valign="top">
<div class="content" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
<table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background: #fff; margin: 0; padding: 0; border: 1px solid #e9e9e9;">
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
<table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 20px; font-weight:bold; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
{{ trans('user::auth.welcome title') }}
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
{{ trans('user::auth.please confirm email') }}
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
{{ trans('user::auth.additional confirm email message') }}
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
<a href="{{ URL::to('auth/activate/' . $user['id'] . '/' . $activationCode) }}" class="btn-primary" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background: #348eda; margin: 0; padding: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">{{ trans('user::auth.confirm email button') }}</a>
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
&mdash; {{ trans('user::auth.end greeting') }}
</td>
</tr>
</table>
</td>
</tr>
</table>
<div class="footer" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
<table width="100%" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
</table>
</div></div>
</td>
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0;" valign="top"></td>
</tr>
</table>
</body>
</html>
@extends('layouts.account')
@section('title')
{{ trans('user::auth.login') }} | @parent
@stop
@section('content')
<div class="login-logo">
<a href="{{ url('/') }}">{{ setting('core::site-name') }}</a>
</div>
<!-- /.login-logo -->
<div class="login-box-body">
<p class="login-box-msg">{{ trans('user::auth.sign in welcome message') }}</p>
@include('partials.notifications')
{!! Form::open(['route' => 'login.post']) !!}
<div class="form-group has-feedback {{ $errors->has('email') ? ' has-error' : '' }}">
<input type="email" class="form-control" autofocus
name="email" placeholder="{{ trans('user::auth.email') }}" value="{{ old('email')}}">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
{!! $errors->first('email', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group has-feedback {{ $errors->has('password') ? ' has-error' : '' }}">
<input type="password" class="form-control"
name="password" placeholder="{{ trans('user::auth.password') }}" value="{{ old('password')}}">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
{!! $errors->first('password', '<span class="help-block">:message</span>') !!}
</div>
<div class="row">
<div class="col-xs-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" name="remember_me"> {{ trans('user::auth.remember me') }}
</label>
</div>
</div>
<div class="col-xs-4">
<button type="submit" class="btn btn-primary btn-block btn-flat">
{{ trans('user::auth.login') }}
</button>
</div>
</div>
</form>
<a href="{{ route('reset')}}">{{ trans('user::auth.forgot password') }}</a><br>
@if (config('asgard.user.config.allow_user_registration'))
<a href="{{ route('register')}}" class="text-center">{{ trans('user::auth.register')}}</a>
@endif
</div>
@stop
@extends('layouts.account')
@section('title')
{{ trans('user::auth.register') }} | @parent
@stop
@section('content')
<div class="register-logo">
<a href="{{ url('/') }}">{{ setting('core::site-name') }}</a>
</div>
<div class="register-box-body">
<p class="login-box-msg">{{ trans('user::auth.register') }}</p>
@include('partials.notifications')
{!! Form::open(['route' => 'register.post']) !!}
<div class="form-group has-feedback {{ $errors->has('email') ? ' has-error has-feedback' : '' }}">
<input type="email" name="email" class="form-control" autofocus
placeholder="{{ trans('user::auth.email') }}" value="{{ old('email') }}">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
{!! $errors->first('email', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group has-feedback {{ $errors->has('password') ? ' has-error has-feedback' : '' }}">
<input type="password" name="password" class="form-control" placeholder="{{ trans('user::auth.password') }}">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
{!! $errors->first('password', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group has-feedback {{ $errors->has('password_confirmation') ? ' has-error has-feedback' : '' }}">
<input type="password" name="password_confirmation" class="form-control" placeholder="{{ trans('user::auth.password confirmation') }}">
<span class="glyphicon glyphicon-log-in form-control-feedback"></span>
{!! $errors->first('password_confirmation', '<span class="help-block">:message</span>') !!}
</div>
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-primary btn-block btn-flat">{{ trans('user::auth.register me') }}</button>
</div>
</div>
{!! Form::close() !!}
<a href="{{ route('login') }}" class="text-center">{{ trans('user::auth.I already have a membership') }}</a>
</div>
@stop
@extends('layouts.account')
@section('title')
{{ trans('user::auth.reset password') }} | @parent
@stop
@section('content')
<div class="login-logo">
<a href="{{ url('/') }}">{{ setting('core::site-name') }}</a>
</div>
<!-- /.login-logo -->
<div class="login-box-body">
<p class="login-box-msg">{{ trans('user::auth.to reset password complete this form') }}</p>
@include('partials.notifications')
{!! Form::open(['route' => 'reset.post']) !!}
<div class="form-group has-feedback {{ $errors->has('email') ? ' has-error' : '' }}">
<input type="email" class="form-control" autofocus
name="email" placeholder="{{ trans('user::auth.email') }}" value="{{ old('email')}}">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
{!! $errors->first('email', '<span class="help-block">:message</span>') !!}
</div>
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-primary btn-block btn-flat pull-right">
{{ trans('user::auth.reset password') }}
</button>
</div>
</div>
{!! Form::close() !!}
<a href="{{ route('login') }}" class="text-center">{{ trans('user::auth.I remembered my password') }}</a>
</div>
@stop
@extends('layouts.account')
@section('title')
{{ trans('user::auth.reset password') }} | @parent
@stop
@section('content')
<div class="login-logo">
<a href="{{ url('/') }}">{{ setting('core::site-name') }}</a>
</div>
<div class="login-box-body">
<p class="login-box-msg">{{ trans('user::auth.reset password') }}</p>
@include('partials.notifications')
{!! Form::open() !!}
<div class="form-group has-feedback {{ $errors->has('password') ? ' has-error' : '' }}">
<input type="password" class="form-control" autofocus
name="password" placeholder="{{ trans('user::auth.password') }}">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
{!! $errors->first('password', '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group has-feedback {{ $errors->has('password_confirmation') ? ' has-error has-feedback' : '' }}">
<input type="password" name="password_confirmation" class="form-control" placeholder="{{ trans('user::auth.password confirmation') }}">
<span class="glyphicon glyphicon-log-in form-control-feedback"></span>
{!! $errors->first('password_confirmation', '<span class="help-block">:message</span>') !!}
</div>
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-primary btn-block btn-flat pull-right">
{{ trans('user::auth.reset password') }}
</button>
</div>
</div>
{!! Form::close() !!}
</div>
@stop
<?php
namespace Modules\User\Services;
use Modules\User\Contracts\Authentication;
use Modules\User\Events\UserHasRegistered;
use Modules\User\Repositories\RoleRepository;
class UserRegistration
{
/**
* @var Authentication
*/
private $auth;
/**
* @var RoleRepository
*/
private $role;
/**
* @var array
*/
private $input;
public function __construct(Authentication $auth, RoleRepository $role)
{
$this->auth = $auth;
$this->role = $role;
}
/**
* @param array $input
* @return mixed
*/
public function register(array $input)
{
$this->input = $input;
$user = $this->createUser();
if ($this->hasProfileData()) {
$this->createProfileForUser($user);
}
$this->assignUserToUsersGroup($user);
event(new UserHasRegistered($user));
return $user;
}
private function createUser()
{
return $this->auth->register((array) $this->input);
}
private function assignUserToUsersGroup($user)
{
$role = $this->role->findByName(config('asgard.user.config.default_role'));
$this->auth->assignRole($user, $role);
}
/**
* Check if the request input has a profile key
* @return bool
*/
private function hasProfileData()
{
return isset($this->input['profile']);
}
/**
* Create a profile for the given user
* @param $user
*/
private function createProfileForUser($user)
{
$profileData = array_merge($this->input['profile'], ['user_id' => $user->id]);
app('Modules\Profile\Repositories\ProfileRepository')->create($profileData);
}
}
<?php
namespace Modules\User\Services;
use Modules\User\Contracts\Authentication;
use Modules\User\Events\UserHasBegunResetProcess;
use Modules\User\Exceptions\InvalidOrExpiredResetCode;
use Modules\User\Exceptions\UserNotFoundException;
use Modules\User\Repositories\UserRepository;
class UserResetter
{
/**
* @var UserRepository
*/
private $user;
/**
* @var Authentication
*/
private $auth;
public function __construct(UserRepository $user, Authentication $auth)
{
$this->user = $user;
$this->auth = $auth;
}
/**
* Start the reset password process for given credentials (email)
* @param array $credentials
* @throws UserNotFoundException
*/
public function startReset(array $credentials)
{
$user = $this->findUser($credentials);
$code = $this->auth->createReminderCode($user);
event(new UserHasBegunResetProcess($user, $code));
}
/**
* Finish the reset process
* @param array $data
* @return mixed
* @throws InvalidOrExpiredResetCode
* @throws UserNotFoundException
*/
public function finishReset(array $data)
{
$user = $this->user->find(array_get($data, 'userId'));
if ($user === null) {
throw new UserNotFoundException();
}
$code = array_get($data, 'code');
$password = array_get($data, 'password');
if (! $this->auth->completeResetPassword($user, $code, $password)) {
throw new InvalidOrExpiredResetCode();
}
return $user;
}
/**
* @param array $credentials
* @return mixed
* @throws UserNotFoundException
*/
private function findUser(array $credentials)
{
$user = $this->user->findByCredentials((array) $credentials);
if ($user === null) {
throw new UserNotFoundException();
}
return $user;
}
}
<?php
namespace Modules\User\Sidebar;
use Maatwebsite\Sidebar\Group;
use Maatwebsite\Sidebar\Item;
use Maatwebsite\Sidebar\Menu;
use Modules\User\Contracts\Authentication;
class SidebarExtender implements \Maatwebsite\Sidebar\SidebarExtender
{
/**
* @var Authentication
*/
protected $auth;
/**
* @param Authentication $auth
*
* @internal param Guard $guard
*/
public function __construct(Authentication $auth)
{
$this->auth = $auth;
}
/**
* @param Menu $menu
*
* @return Menu
*/
public function extendWith(Menu $menu)
{
$menu->group(trans('workshop::workshop.title'), function (Group $group) {
$group->item(trans('user::users.title.users'), function (Item $item) {
$item->weight(0);
$item->icon('fa fa-user');
$item->authorize(
$this->auth->hasAccess('user.users.index') or $this->auth->hasAccess('user.roles.index')
);
$item->item(trans('user::users.title.users'), function (Item $item) {
$item->weight(0);
$item->icon('fa fa-user');
$item->route('admin.user.user.index');
$item->authorize(
$this->auth->hasAccess('user.users.index')
);
});
$item->item(trans('user::roles.title.roles'), function (Item $item) {
$item->weight(1);
$item->icon('fa fa-flag-o');
$item->route('admin.user.role.index');
$item->authorize(
$this->auth->hasAccess('user.roles.index')
);
});
});
});
$menu->group(trans('user::users.my account'), function (Group $group) {
$group->weight(110);
$group->item(trans('user::users.api-keys'), function (Item $item) {
$item->weight(1);
$item->icon('fa fa-key');
$item->route('admin.account.api.index');
$item->authorize(
$this->auth->hasAccess('account.api-keys.index')
);
});
});
return $menu;
}
}
<?php
namespace Modules\User\Tests\Permissions;
use Modules\Core\Tests\BaseTestCase;
use Modules\User\Permissions\PermissionManager;
class PermissionManagerTest extends BaseTestCase
{
/**
* @test
*/
public function it_should_clean_permissions()
{
$input = [
'permission1' => '1',
'permission2' => '1',
'permission3' => '-1',
'permission4' => '-1',
'permission5' => '0',
'permission6' => '0',
];
$expected = [
'permission1' => true,
'permission2' => true,
'permission3' => false,
'permission4' => false,
];
$manager = new PermissionManager();
$actual = $manager->clean($input);
$this->assertSame($expected, $actual, 'The PermissionManager should clean the permissions and fix their states.');
}
}
url: https://github.com/AsgardCms/User
versions:
"2.0@unreleased":
added:
- Laravel 5.2 compatibility
- Added api keys management per user. With API middleware to protect internal APIs and public APIs.
- <code>Authentication</code> contract has been moved to the User module (from Core Module)
- Adding hasAccess method on UserInterface to check for given permission(s)
- Adding a token can middleware to validate API routes for permissions
- Completely revamped user / role permission UI to allow easy inheritance from role
- Permissions have a nice label displayed
removed:
- Removing Sentry and Usher user providers
- Removing laracasts/flash dependency
changed:
- Using new more flexible way of handle permissions via middleware
- Refactor and restructure the permissions to allow inheritance via GUI
- Rename the users.php file to config.php
- Use Mailable classes from laravel 5.3
"1.18.0":
changed:
- User reset process is now handled by a service class
- Using the <code>$router</code> variable over the route helpers
"1.17.0":
added:
- Adding ability to send a reset password email to user
"1.16.1":
added:
- Adding method to create a role without triggering the event
"1.16.0":
changed:
- Fire event on manual user creation
"1.15.1":
changed:
- Config vars ineffective when instantiating with attributes
"1.15.0":
added:
- Adding config option to disable the user registration routes
changed:
- Adding autofocus on the first fields of authentication views
"1.14.0":
changed:
- Removed language files, they are now in the translation module
added:
- Adding a wysiwyg settings field.
"1.13.1":
changed:
- Fixed yaml structure
"1.13.0":
changed:
- Seeding the Translation module permissions on init
"1.12.0":
changed:
- New and updated authentication views. <strong>Important If you published the auth views, they need to be re-published</strong>
"1.11.0":
changed:
- Manual inclusing of iCheck css file has been removed
- Use the new datatables way of marking column not sortable
"1.10.1":
changed:
- Adding the permissions for the Themes part of the workshop Module on initial seed
"1.10.0":
changed:
- The <code>PermissionManager</code> class has been moved to the User Module
- Fixing issue with basic permissions
"1.9.0":
changed:
- Fixing user manual activation via backend
- Removing deprecated code usage
- Minor consistency changes
"1.8.0":
added:
- Added Russian translations
changed:
- Improving german translations
"1.7.0":
added:
- Chinese Simplified language
- Added a <code>UserHasActivatedAccount</code> event
"1.6.0":
added:
- Dutch and Portuguese language
"1.5.0":
added:
- Spanish translations
"1.4.0":
changed:
- Default fallback user provider set to Sentinel
"1.3.1":
changed:
- Fixing user update for sentinel
"1.3.0":
changed:
- Use helper functions in controllers
- Use manual route definition over the route resource shortcut
"1.2.0":
added:
- Set the user fillable fields dynamically from the user configuration file
"1.1.0":
added:
- Adding the loginNames property on the Sentinel User entity
- Adding configuration to setup which login column names to use
changed:
- Cleaning up <code>composers.php</code> file
"1.0.11":
added:
- Added a UserWasUpdated event
- Added a RoleWasUpdated event
- Flushing sidebar cache when user or role was updated
"1.0.10":
changed:
- Fixing datatable
"1.0.9":
changed:
- Changing index views ordering of columns
"1.0.8":
changed:
- Sentinel - checking if user is logged in before checking for permissions
"1.0.7":
changed:
- Remove the Authentication contract injection from the AuthController
"1.0.6":
changed:
- Make the UsernameViewComposer independent
"1.0.5":
changed:
- Fix the hasAccess method on the sentry implementation
"1.0.4":
added:
- Using new sidebar extender class
removed:
- Old SidebarViewComposer
"1.0.3":
added:
- Implementing the new <code>id</code> method on Sentry and Sentinel Authentication implementations
"1.0.2":
changed:
- Adding changelog file
"1.0.1":
changed:
- Using tagged versions of modules
"1.0.0":
changed:
- Initial release
{
"name": "asgardcms/user-module",
"type": "asgard-module",
"description": "User module for AsgardCMS. Handles the authentication and authorisation as well as the user management.",
"keywords": [
"asgardcms",
"user",
"authentication",
"authorisation"
],
"license": "MIT",
"authors": [
{
"name": "Nicolas Widart",
"email": "info@asgardcms.com",
"role": "Developer"
}
],
"support": {
"email": "support@asgardcms.com",
"issues": "https://github.com/AsgardCms/Platform/issues",
"source": "https://github.com/AsgardCms/User"
},
"require": {
"php": ">=5.6",
"composer/installers": "~1.0",
"asgardcms/core-module": "~2.0",
"ramsey/uuid": "^3.4"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"orchestra/testbench": "3.3.*",
"scrutinizer/ocular": "~1.1",
"fzaninotto/faker": "~1.5",
"mockery/mockery": "^0.9.4",
"phpro/grumphp": "^0.9.1",
"friendsofphp/php-cs-fixer": "^1.11"
},
"autoload": {
"psr-4": {
"Modules\\User\\": ".",
"Modules\\": "Modules/"
}
},
"autoload-dev": {
"psr-4": {
"Modules\\User\\Tests\\": "Tests"
}
},
"extra": {
"branch-alias": {
"dev-2.0": "2.0.x-dev"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
<?php
view()->composer(
[
'user::admin.partials.permissions',
'user::admin.partials.permissions-create',
],
'Modules\User\Composers\PermissionsViewComposer'
);
view()->composer(
[
'partials.sidebar-nav',
'partials.top-nav',
'layouts.master',
'partials.*',
],
'Modules\User\Composers\UsernameViewComposer'
);
parameters:
git_dir: .
bin_dir: vendor/bin
stop_on_failure: true
tasks:
phpcsfixer:
config_file: .php_cs
composer:
file: ./composer.json
jsonlint:
ignore_patterns: []
<?php
if (function_exists('current_permission_value') === false) {
function current_permission_value($model, $permissionTitle, $permissionAction)
{
$value = array_get($model->permissions, "$permissionTitle.$permissionAction");
if ($value === true) {
return 1;
}
if ($value === false) {
return -1;
}
return 0;
}
}
{
"name": "User",
"alias": "user",
"description": "The user module is responsible for managing users and permissions.",
"keywords": [],
"version": "2.0.0",
"active": 1,
"order": 1,
"providers": [
"Modules\\User\\Providers\\UserServiceProvider",
"Modules\\User\\Providers\\EventServiceProvider",
"Modules\\User\\Providers\\RouteServiceProvider"
],
"aliases": {
"Sentinel": "Cartalyst\\Sentinel\\Laravel\\Facades\\Sentinel",
"Sentry": "Cartalyst\\Sentry\\Facades\\Laravel\\Sentry",
"Activation": "Cartalyst\\Sentinel\\Laravel\\Facades\\Activation",
"Reminder": "Cartalyst\\Sentinel\\Laravel\\Facades\\Reminder"
},
"files": [
"composers.php",
"helpers.php"
]
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./Tests/</directory>
</testsuite>
</testsuites>
</phpunit>
# User module
[![Latest Version](https://img.shields.io/packagist/v/asgardcms/user-module.svg?style=flat-square)](https://github.com/asgardcms/user/releases)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Quality Score](https://img.shields.io/scrutinizer/g/asgardcms/user.svg?style=flat-square)](https://scrutinizer-ci.com/g/asgardcms/user)
[![SensioLabs Insight](https://img.shields.io/sensiolabs/i/304d1d01-3347-4958-915f-b2daabfe5f5a.svg)](https://insight.sensiolabs.com/projects/304d1d01-3347-4958-915f-b2daabfe5f5a)
[![CodeClimate](https://img.shields.io/codeclimate/github/AsgardCms/User.svg)](https://codeclimate.com/github/AsgardCms/User)
[![Total Downloads](https://img.shields.io/packagist/dd/asgardcms/user-module.svg?style=flat-square)](https://packagist.org/packages/asgardcms/user-module)
[![Total Downloads](https://img.shields.io/packagist/dm/asgardcms/user-module.svg?style=flat-square)](https://packagist.org/packages/asgardcms/user-module)
[![Total Downloads](https://img.shields.io/packagist/dt/asgardcms/user-module.svg?style=flat-square)](https://packagist.org/packages/asgardcms/user-module)
[![Slack](http://slack.asgardcms.com/badge.svg)](http://slack.asgardcms.com/)
| Branch | Travis-ci |
| ---------------- | --------------- |
| master | [![Build Status](https://travis-ci.org/AsgardCms/User.svg?branch=master)](https://travis-ci.org/AsgardCms/User) |
## Resources
- [Contribute to AsgardCMS](https://asgardcms.com/en/docs/getting-started/contributing)
- [License](LICENSE.md)
- [Documentation](http://asgardcms.com/docs/user-module/drivers)
## Info
All AsgardCMS modules respect [Semantic Versioning](http://semver.org/).
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment