Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth component #183

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions components/auth/app/Controllers/UsersController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace App\Controllers;

use App;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Access\Gate as AccessGate;
use Symfony\Component\HttpKernel\Exception\HttpException;

class UsersController
{
public function index()
{
return "listing the users<br><br><form method='post'><input type='submit'></form>";
}

public function store(Request $request)
{
$container = App::getInstance();

$user = $container['auth']->user();

if (! $container[AccessGate::class]->allows('add-user', $user)) {
throw new HttpException(403);
}

return "creating new user";
}
}
56 changes: 56 additions & 0 deletions components/auth/app/Eloquent/Auth/Access/Authorizable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace App\Eloquent\Auth\Access;

use Illuminate\Contracts\Auth\Access\Gate;

trait Authorizable
{
/**
* Determine if the entity has the given abilities.
*
* @param iterable|string $abilities
* @param array|mixed $arguments
* @return bool
*/
public function can($abilities, $arguments = [])
{
return app(Gate::class)->forUser($this)->check($abilities, $arguments);
}

/**
* Determine if the entity has any of the given abilities.
*
* @param iterable|string $abilities
* @param array|mixed $arguments
* @return bool
*/
public function canAny($abilities, $arguments = [])
{
return app(Gate::class)->forUser($this)->any($abilities, $arguments);
}

/**
* Determine if the entity does not have the given abilities.
*
* @param iterable|string $abilities
* @param array|mixed $arguments
* @return bool
*/
public function cant($abilities, $arguments = [])
{
return ! $this->can($abilities, $arguments);
}

/**
* Determine if the entity does not have the given abilities.
*
* @param iterable|string $abilities
* @param array|mixed $arguments
* @return bool
*/
public function cannot($abilities, $arguments = [])
{
return $this->cant($abilities, $arguments);
}
}
127 changes: 127 additions & 0 deletions components/auth/app/Eloquent/Auth/Access/AuthorizesRequests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

namespace App\Eloquent\Auth\Access;

use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Support\Str;

trait AuthorizesRequests
{
/**
* Authorize a given action for the current user.
*
* @param mixed $ability
* @param mixed|array $arguments
* @return \Illuminate\Auth\Access\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function authorize($ability, $arguments = [])
{
[$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);

return app(Gate::class)->authorize($ability, $arguments);
}

/**
* Authorize a given action for a user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|mixed $user
* @param mixed $ability
* @param mixed|array $arguments
* @return \Illuminate\Auth\Access\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function authorizeForUser($user, $ability, $arguments = [])
{
[$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);

return app(Gate::class)->forUser($user)->authorize($ability, $arguments);
}

/**
* Guesses the ability's name if it wasn't provided.
*
* @param mixed $ability
* @param mixed|array $arguments
* @return array
*/
protected function parseAbilityAndArguments($ability, $arguments)
{
if (is_string($ability) && strpos($ability, '\\') === false) {
return [$ability, $arguments];
}

$method = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];

return [$this->normalizeGuessedAbilityName($method), $ability];
}

/**
* Normalize the ability name that has been guessed from the method name.
*
* @param string $ability
* @return string
*/
protected function normalizeGuessedAbilityName($ability)
{
$map = $this->resourceAbilityMap();

return $map[$ability] ?? $ability;
}

/**
* Authorize a resource action based on the incoming request.
*
* @param string $model
* @param string|null $parameter
* @param array $options
* @param \Illuminate\Http\Request|null $request
* @return void
*/
public function authorizeResource($model, $parameter = null, array $options = [], $request = null)
{
$parameter = $parameter ?: Str::snake(class_basename($model));

$middleware = [];

foreach ($this->resourceAbilityMap() as $method => $ability) {
$modelName = in_array($method, $this->resourceMethodsWithoutModels()) ? $model : $parameter;

$middleware["can:{$ability},{$modelName}"][] = $method;
}

foreach ($middleware as $middlewareName => $methods) {
$this->middleware($middlewareName, $options)->only($methods);
}
}

/**
* Get the map of resource methods to ability names.
*
* @return array
*/
protected function resourceAbilityMap()
{
return [
'index' => 'viewAny',
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
];
}

/**
* Get the list of resource methods which do not have model parameters.
*
* @return array
*/
protected function resourceMethodsWithoutModels()
{
return ['index', 'create', 'store'];
}
}
22 changes: 22 additions & 0 deletions components/auth/app/Eloquent/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Eloquent;

use App\Eloquent\Auth\Access\Authorizable;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model;

class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;

protected $guarded = [];
}
21 changes: 21 additions & 0 deletions components/auth/app/Middleware/Authenticate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;

class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return 'Error Authenticate. Please <a href="/login">login</a>';
}
}
}
26 changes: 26 additions & 0 deletions components/auth/app/Middleware/RedirectIfAuthenticated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (isset($_SESSION['user'])) {
return 'Error Authenticate';
}

return $next($request);
}
}
47 changes: 47 additions & 0 deletions components/auth/app/Middleware/StartSession.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace App\Middleware;

use Closure;
use Symfony\Component\HttpFoundation\Cookie;

class StartSession
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$container = \App::getInstance();

if (session_status() == PHP_SESSION_NONE) {
// In order to maintain the session between requests, we need to populate the
// session ID from the supplied cookie
$cookieName = $container['session']->getName();

if (isset($_COOKIE[$cookieName])) {
if ($sessionId = $_COOKIE[$cookieName]) {
$container['session']->setId($sessionId);
}
}

// Boot the session
$container['session']->start();
}

$response = $next($request);

$response->headers->setCookie(new Cookie(
$container['session']->getName(), $container['session']->getId(),
));

$container['session']->save();

return $response;
}
}
13 changes: 13 additions & 0 deletions components/auth/app/Policies/UserPolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Policies;

use App\Eloquent\User;

class UserPolicy
{
public function add(User $user)
{
return $user->email === 'user';
}
}
17 changes: 17 additions & 0 deletions components/auth/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"require": {
"illuminate/auth": "^8.23",
"illuminate/database": "^8.23",
"illuminate/events": "^8.23",
"illuminate/config": "^8.23",
"illuminate/hashing": "^8.23",
"illuminate/session": "^8.23",
"illuminate/cookie": "^8.23",
"illuminate/routing": "^8.24"
},
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
Loading