I've added an ACL to my website but when I test the result of my role variable in the SecurityPlugin.php file I get the result twice.
Why does Phalcon show the var_dump of $role twice? I'm fairly new to this framework and my initial thought was it might me due to routing in Phalcon?
Phalcon version: 3.0.3
\app\plugins\SecurityPlugin.php
use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Adapter\Memory as AclList;
use Phalcon\Acl\Resource;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
class SecurityPlugin extends Plugin
{
/**
* Returns an existing or new access control list
*
* #returns AclList
*/
public function getAcl()
{
if (!isset($this->persistent->acl)) {
$acl = new AclList();
$acl->setDefaultAction(Acl::DENY);
// Register roles
$roles = [
'admins' => new Role(
'admins',
'Website administrators'
),
'users' => new Role(
'users',
'Member privileges, granted after sign in.'
),
'guests' => new Role(
'guests',
'Anyone browsing the site who is not signed in is considered to be a "Guest".'
)
];
foreach ($roles as $role) {
$acl->addRole($role);
}
//Private area resources
$privateResources = array(
'account' => array('*')
);
$privateResourcesAdmin = array(
'admin' => array('*')
);
//Public area resources
$publicResources = array(
'index' => array('*'),
'register' => array('*'),
'errors' => array('show401', 'show404', 'show500'),
'register' => array('*'),
'login' => array('*'),
'logout' => array('*')
);
foreach ($privateResources as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
foreach ($privateResourcesAdmin as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
foreach ($publicResources as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
//Grant access to public areas to users, admins and guests
foreach ($roles as $role) {
foreach ($publicResources as $resource => $actions) {
foreach ($actions as $action){
$acl->allow($role->getName(), $resource, $action);
}
}
}
//Grant access to private area to role Users
foreach ($privateResources as $resource => $actions) {
foreach ($actions as $action){
$acl->allow('users', $resource, $action);
}
}
foreach ($privateResourcesAdmin as $resource => $actions) {
foreach ($actions as $action){
$acl->allow('admins', $resource, $action);
}
}
//The acl is stored in session, APC would be useful here too
$this->persistent->acl = $acl;
}
return $this->persistent->acl;
}
/**
* This action is executed before execute any action in the application
*
* #param Event $event
* #param Dispatcher $dispatcher
* #return bool
*/
public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher){
$auth = $this->session->get('auth');
if (!$auth){
$role = 'guests';
} else {
if ($this->session->has("account_type")) {
$type = $this->session->get("account_type");
if($type == 99){
$role = 'admins';
} else {
$role = 'users';
}
}
}
var_dump($role);
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
$acl = $this->getAcl();
if (!$acl->isResource($controller)) {
$dispatcher->forward([
'controller' => 'errors',
'action' => 'show404'
]);
return false;
}
$allowed = $acl->isAllowed($role, $controller, $action);
if (!$allowed) {
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show401'
));
$this->session->destroy();
return false;
}
}
}
\public\index.php
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Dispatcher; //Used for ACL list and authorization routing
use Phalcon\Events\Manager as EventsManager; //Used for ACL List
use Phalcon\Mvc\Router; //Used for routing logout page
error_reporting(E_ALL);
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
try {
/**
* The FactoryDefault Dependency Injector automatically registers
* the services that provide a full stack framework.
*/
$di = new FactoryDefault();
/**
* Read services
*/
include APP_PATH . "/config/services.php";
/**
* Get config service for use in inline setup below
*/
$config = $di->getConfig();
/**
* Include Autoloader
*/
include APP_PATH . '/config/loader.php';
//This makes sure the routes are correctly handled for authorized/unauthorized in people
/**
* MVC dispatcher
*/
$di->set("dispatcher", function () use ($di) {
// Create an events manager
$eventsManager = $di->getShared('eventsManager');
/**
*Check if the user is allowed to access certain action using the SecurityPlugin
*Listen for events produced in the dispatcher using the Security plugin
*/
$eventsManager->attach(
"dispatch:beforeExecuteRoute",
new SecurityPlugin()
);
// Handle exceptions and not-found exceptions using NotFoundPlugin
$eventsManager->attach(
"dispatch:beforeException",
new NotFoundPlugin()
);
$dispatcher = new Dispatcher();
// Assign the events manager to the dispatcher
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
/**
* Handle and deploy the application
*/
$application = new \Phalcon\Mvc\Application($di);
echo $application->handle()->getContent();
} catch (\Exception $e) {
echo $e->getMessage() . '<br>';
echo '<pre>' . $e->getTraceAsString() . '</pre>';
}
Because you are doing forward - so this means there is other action executed again and beforeExecuteRoute fired again - that's why 2 times var_dump
Related
So I just want to add login with google feature on my working authentication web app (with Codeigniter Shield package). I've already create a login_google function on Login controller that extends LoginController from shield package like this :
LoginController
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\Shield\Controllers\LoginController;
class Login extends LoginController
{
function __construct()
{
require_once __DIR__ . '/../../vendor/autoload.php';
$this->userModel = new \App\Models\UserModel();
$this->google_client = new \Google_Client();
$this->google_client->setClientId(getenv('OAuth2.clientID'));
$this->google_client->setClientSecret(getenv('OAuth2.clientSecret'));
$this->google_client->setRedirectUri('http://localhost:8080/login_google');
$this->google_client->addScope('email');
$this->google_client->addScope('profile');
}
public function loginView()
{
if (auth()->loggedIn()) {
return redirect()->to(config('Auth')->loginRedirect());
}
/** #var Session $authenticator */
$authenticator = auth('session')->getAuthenticator();
// If an action has been defined, start it up.
if ($authenticator->hasAction()) {
return redirect()->route('auth-action-show');
}
$data['google_button'] = "<a href='".$this->google_client->createAuthUrl()."'><img src='https://developers.google.com/identity/images/btn_google_signin_dark_normal_web.png' /></a>";
return view('login', $data);
}
public function loginAction(): RedirectResponse
{
// Validate here first, since some things,
// like the password, can only be validated properly here.
$rules = $this->getValidationRules();
if (! $this->validate($rules)) {
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$credentials = $this->request->getPost(setting('Auth.validFields'));
$credentials = array_filter($credentials);
$credentials['password'] = $this->request->getPost('password');
$remember = (bool) $this->request->getPost('remember');
/** #var Session $authenticator */
$authenticator = auth('session')->getAuthenticator();
// Attempt to login
$result = $authenticator->remember($remember)->attempt($credentials);
if (! $result->isOK()) {
return redirect()->route('login')->withInput()->with('error', $result->reason());
}
/** #var Session $authenticator */
$authenticator = auth('session')->getAuthenticator();
// If an action has been defined for login, start it up.
if ($authenticator->hasAction()) {
return redirect()->route('auth-action-show')->withCookies();
}
return redirect()->to(config('Auth')->loginRedirect())->withCookies();
}
public function login_google() {
$token = $this->google_client->fetchAccessTokenWithAuthCode($this->request->getVar('code'));
if (!isset($token['error'])) {
$this->google_client->setAccessToken($token['access_token']);
$this->session->set('access_token', $token['access_token']);
$google_service = new \Google\Service\Oauth2($this->google_client);
$data = $google_service->userinfo->get();
$userdata = array();
if ($this->userModel->isAlreadyRegister($data['id'])) {
$userdata = [
'first_name' => $data['givenName'],
'last_name' => $data['familyName'],
'email' => $data['email'],
'avatar' => $data['picture'],
];
$this->userModel->updateUserData($userdata, $data['id']);
} else {
$userdata = [
'first_name' => $data['givenName'],
'last_name' => $data['familyName'],
'email' => $data['email'],
'avatar' => $data['picture'],
'oauth_id' => $data['id'],
];
$this->userModel->insertUserData($userdata);
}
$this->session->set('LoggedUserData', $userdata);
} else {
$this->session->set("error", $token['error']);
return redirect('/register');
}
return redirect()->to('/profile');
}
}
UserModel like this :
UserMode
<?php
namespace App\Models;
use CodeIgniter\Model;
use CodeIgniter\Shield\Models\UserModel as ModelsUserModel;
class UserModel extends ModelsUserModel
{
protected $allowedFields = [
'username',
'status',
'status_message',
'active',
'last_active',
'deleted_at',
'gender',
'first_name',
'last_name',
'avatar',
'phone_number',
'full_address',
'oauth_id',
];
function isAlreadyRegister($authid){
return $this->db->table('users')->getWhere(['id'=>$authid])->getRowArray()>0?true:false;
}
function updateUserData($userdata, $authid){
$this->db->table("users")->where(['id'=>$authid])->update($userdata);
}
function insertUserData($userdata){
$this->db->table("users")->insert($userdata);
}
}
But everytime I clicked sign in with google button, it won't work (the interface for choosing google account to authenticate is worked) and always return to login page
am I missing something when combining CodeIgniter Shield with Google Oauth ? Anyone can help ? TIA
A new package has been created for OAuth with Shield package: https://github.com/datamweb/shield-oauth
You can use it instead of your own one.
Sorry I feel like really stuck here.
I have a plugin introducing a new Rest API controller (WP_REST_Controller) with basically a single endpoint which uses a separate class as a client to fetch some data. Let's say:
#my_plugin.php
function register_items_routes() {
if ( ! class_exists( 'WP_REST_My_Controller' ) ) {
require_once __DIR__ . '/class-wp-my-controller.php';
}
$controller = new WP_REST_My_Controller();
$controller->register_routes();
}
add_action( 'rest_api_init', 'register_items_routes' );
_
#class-wp-my-controller.php
class WP_REST_My_Controller extends WP_REST_Controller {
/**
* Registers the routes.
*/
public function register_routes() {
$namespace = 'my/namespace';
$path = 'get-items';
register_rest_route( $namespace, '/' . $path, [
array(
'methods' => 'GET',
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' )
),
] );
}
public function get_items_permissions_check( $request ) {
return true;
}
/**
* Get items from My_Class and return them.
*
* #param WP_REST_Request $request The incoming HTTP request.
*
* #return WP_REST_Response|WP_Error The response containing the items in JSON, WP_Error in case of error.
*/
public function get_items( $request ) {
$client = new My_Class();
try {
$items = $client->fetch_some_items();
} catch ( Exception $e ) {
return new WP_Error(
'some-client-error',
$e->getMessage()
);
// Code to be tested. - Do some stuff with items and return.
return new WP_REST_Response( $items );
}
How am I supposed to stub the My_Class dependency from PhpUnit in order to return a predefined set of items which I could test with?
public function test_get_items() {
$request = new WP_REST_Request( 'GET', '/my/namespace/get-items' );
$data = rest_get_server()->dispatch( $request );
$expected_items = [
'some_key1' => 'some_value1',
'some_key2' => 'some_value2',
];
$this->assertTrue( count($data['items']) == count($expected_items) );
}
I'm currently using Phalcon 3.3 / PHP 7.2 (Ubuntu 18.04 LTS / Windows 10)
I created a custom SecurityPlugin file to verify user permission to access routes. I've defined my roles, resources and permission using Phalcon's ACL.
Here's my SecurityPlugin class
<?php
use Phalcon\Acl;
use Phalcon\Acl\Resource;
use Phalcon\Acl\Role;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;
/**
* Class SecurityPlugin
*
* This is the security plugin that makes sure users access the modules they are assigned to
*
*/
class SecurityPlugin extends Plugin
{
private function _getAcl()
{
if(!isset($this -> persistent -> acl))
{
$acl = new AclList();
$acl -> setDefaultAction(Acl::DENY);
//Add Roles
$roles = [
'base_acc' => new Role(
'BaseAcc',
'This role represents the standard users that are allowed on the platform'
),
'guest' => new Role(
'Guest',
'This is the default role assigned to users that are not logged in'
)
];
//Register Roles
foreach ($roles as $role) {
$acl -> addRole($role);
}
//Add Standard User Resources
$standardResources = [
'store' => ['index']
];
//Add Public Resources
$publicResources = [
'index' => ['index'],
'auth' => ['index', 'login', 'logout', 'register', 'confirmEmail', 'continueReg', 'finishReg', 'verifyPasswordToken', 'forgotPassword', 'updatePassword'],
'errors' => ['show404', 'show503', 'errorConfirm']
];
//Register Standard User Resources
foreach ($standardResources as $resource => $actions)
{
$acl -> addResource(new Resource($resource), $actions);
}
//Register Public Resources
foreach ($publicResources as $resource => $actions)
{
$acl -> addResource(new Resource($resource), $actions);
}
//Register Public Resources to all roles
foreach ($roles as $role) {
foreach ($publicResources as $resource => $actions){
foreach($actions as $action){
$acl -> allow($role -> getName(), $resource, $action);
}
}
}
//Register Standard Resources to standard User Role
foreach ($standardResources as $resource => $actions){
foreach($actions as $action){
$acl -> allow('BaseAcc', $resource, $action);
}
}
$this -> persistent -> acl = $acl;
}
return $this -> persistent -> acl;
}
public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
{
$auth = $this->session->get('auth');
if (!$auth){
$role = 'Guests';
} else {
$role = 'BaseAcc';
}
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
$acl = $this->_getAcl();
if (!$acl->isResource($controller)) {
$dispatcher->forward([
'controller' => 'errors',
'action' => 'show404'
]);
return false;
}
$allowed = $acl->isAllowed($role, $controller, $action);
if (!$allowed) {
$dispatcher->forward([
'controller' => 'errors',
'action' => 'show401'
]);
//$this->session->destroy();
return false;
}
//Checks thr current user role
//$roles = [];
/*$auth = $this -> session -> get('auth');
if(!$auth)
{
$role = 'Guest';
}
else
{
$role = 'BaseAcc';
}
$acl = $this -> _getAcl();
$controller = $dispatcher -> getControllerName();
$action = $dispatcher -> getActionName();
$lastController = $dispatcher ->getLastController();
if(!$acl -> isResource($controller))
{
$dispatcher -> forward([
'controller' => 'errors',
'action' => 'show404'
]);
return false;
}
if(!$acl -> isAllowed($role, $controller, $action))
{
$dispatcher -> forward([
'controller' => 'errors',
'action' => 'show503'
]);
return false;
}*/
}
}
My part of my application bootstrap:
<?php
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
error_reporting(E_ALL);
use Phalcon\Mvc\View as ViewEngine;
use Phalcon\Mvc\Model\MetaData\Files as MetaDataAdapter;
use Phalcon\Mvc\Application as AppEngine;
use Phalcon\Flash\Session as FlashService;
use Phalcon\Flash\Direct as FlashDirect;
use Phalcon\Session\Adapter\Files as SessionHandler;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
//use Phalcon\Logger\Adapter\File as LogService;
use Phalcon\Logger\Factory as LogFactory;
try{
//Try our Debugger
// = new Phalcon\Debug();
//$debug -> listen(true, true);
//Application Loader
$loader = new Phalcon\Loader();
//Register Working Directories
$loader -> registerDirs([
APP_PATH . '/controllers',
APP_PATH . '/config',
APP_PATH . '/models',
APP_PATH . '/cache',
APP_PATH . '/plugins',
BASE_PATH . '/vendor',
]);
//Register Namespaces
$loader -> registerNamespaces([
//'AgroTech\Models' => APP_PATH . '/models',
'AgroTech\Plugins' => APP_PATH . '/plugins'
]);
//Register Loader
$loader -> register();
// Use composer autoloader to load vendor classes
require_once BASE_PATH . '/vendor/autoload.php';
$di = new Phalcon\Di\FactoryDefault();
...
$di -> set('dispatcher', function() use ($di){
$eventsManager = $di->getShared('eventsManager');
//Bind our Custom Event Handlers
$eventsManager -> attach('dispatch:beforeExecuteRoute', new SecurityPlugin());
$eventsManager -> attach('dispatch:beforeException', new NotFoundPlugin());
//xdebug_print_function_stack();
$dispatcher = new Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
...
$app = new AppEngine($di);
$response = $app -> handle();
$response -> send();
} catch(Phalcon\Exception $e){
echo "Exception: " . $e -> getMessage();
echo '<pre>' . $e -> getTraceAsString() . '</pre>';
}
However, binding the event 'dispatch:beforeExecuteRoute' with my SecurityPlugin gives me a 503 error. Disabling it makes all my pages acessible. And also, disabling my NotFoundPlugin (which handles invalid routes), I get a Dispatcher Cyclic routing error
Is there something I'm doing wrong?
Note: I based my SecurityPlugin implementation off https://github.com/phalcon/invo
What i can say? Just debug it with xdebug or even var_dumps and that's it? Check what is your $auth, controller, action etc in beforeExecuteRoute method and check what isAllowed is returning and how your acl object looks like after creating it and you will find your mistake easy.
one question...If I want to disable email verification upon user registration ( I would like for users to be logged in automatically after registration) how should I do that? Should I change it in the configuration somewhere or should I override controllers and manually enable users and add verification for them? I saw that in previous sylius versions there were a configuration for verification in sylius_user (SyliusUserBundle) but in new version, there is no configuration for that.
Thank you.
//edit//
I have overridden controller for registration(code below) and just got User and enabled it plus logged him in with service provided with sylius.
<?php
namespace AppBundle\Controller;
use Blameable\Fixture\Document\User;
use FOS\RestBundle\View\View;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController as BaseCustomerController;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Sylius\Bundle\UserBundle\Security\UserLogin as UserLogin;
class CustomerController extends BaseCustomerController
{
/**
* #param Request $request
*
* #return Response
*/
public function createAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::CREATE);
$newResource = $this->newResourceFactory->create($configuration, $this->factory);
$form = $this->resourceFormFactory->create($configuration, $newResource);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
$newResource = $form->getData();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $newResource);
}
if ($configuration->hasStateMachine()) {
$this->stateMachine->apply($configuration, $newResource);
}
$newResource->getUser()->enable();
$this->repository->add($newResource);
$this->get('sylius.security.user_login')->login($newResource->getUser());
$this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
return $this->redirectHandler->redirectToResource($configuration, $newResource);
}
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
}
$view = View::create()
->setData([
'configuration' => $configuration,
'metadata' => $this->metadata,
'resource' => $newResource,
$this->metadata->getName() => $newResource,
'form' => $form->createView(),
])
->setTemplate($configuration->getTemplate(ResourceActions::CREATE . '.html'))
;
return $this->viewHandler->handle($configuration, $view);
}
}
You can simply do that by bringing back two classes from this PR:
UserAutoLoginListener
UserRegistrationFormSubscriber
Right I have set up confide user authentication on my Laravel site.
I have ran everything as exactly as they said on the github page. When I direct myself to the user/create page I am presented with the form that I would normally posy me new info into. When I press submit I get this error on this url: /user.
On inspection these are the errors I get:
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException
Controller method not found.
* Handle calls to missing methods on the controller.
*
* #param array $parameters
* #return mixed
*/
public function missingMethod($parameters)
{
throw new NotFoundHttpException("Controller method not found.");
}
15. Symfony\Component\HttpKernel\Exception\NotFoundHttpException
…/vendor/laravel/framework/src/Illuminate/Routing/Controllers/Controller.php290
14. Illuminate\Routing\Controllers\Controller missingMethod
…/vendor/laravel/framework/src/Illuminate/Routing/Controllers/Controller.php302
13. Illuminate\Routing\Controllers\Controller __call
…/app/controllers/UserController.php42
12. User save
…/app/controllers/UserController.php42
11. UserController store
<#unknown>0
My UserController.php is setup like so:
<?php
/*
|--------------------------------------------------------------------------
| Confide Controller Template
|--------------------------------------------------------------------------
|
| This is the default Confide controller template for controlling user
| authentication. Feel free to change to your needs.
|
*/
class UserController extends BaseController {
/**
* Displays the form for account creation
*
*/
public function create()
{
return View::make(Config::get('confide::signup_form'));
}
/**
* Stores new account
*
*/
public function store()
{
$user = new User;
$user->username = Input::get( 'username' );
$user->email = Input::get( 'email' );
$user->password = Input::get( 'password' );
// The password confirmation will be removed from model
// before saving. This field will be used in Ardent's
// auto validation.
$user->password_confirmation = Input::get( 'password_confirmation' );
// Save if valid. Password field will be hashed before save
$user->save();
if ( $user->id )
{
// Redirect with success message, You may replace "Lang::get(..." for your custom message.
return Redirect::action('UserController#login')
->with( 'notice', Lang::get('confide::confide.alerts.account_created') );
}
else
{
// Get validation errors (see Ardent package)
$error = $user->errors()->all(':message');
return Redirect::action('UserController#create')
->withInput(Input::except('password'))
->with( 'error', $error );
}
}
/**
* Displays the login form
*
*/
public function login()
{
if( Confide::user() )
{
// If user is logged, redirect to internal
// page, change it to '/admin', '/dashboard' or something
return Redirect::to('/admin');
}
else
{
return View::make(Config::get('confide::login_form'));
}
}
public function do_login()
{
$input = array(
'email' => Input::get( 'email' ), // May be the username too
'username' => Input::get( 'email' ), // so we have to pass both
'password' => Input::get( 'password' ),
'remember' => Input::get( 'remember' ),
);
// If you wish to only allow login from confirmed users, call logAttempt
// with the second parameter as true.
// logAttempt will check if the 'email' perhaps is the username.
// Get the value from the config file instead of changing the controller
if ( Confide::logAttempt( $input, Config::get('confide::signup_confirm') ) )
{
// Redirect the user to the URL they were trying to access before
// caught by the authentication filter IE Redirect::guest('user/login').
// Otherwise fallback to '/'
// Fix pull #145
return Redirect::intended('/'); // change it to '/admin', '/dashboard' or something
}
else
{
$user = new User;
// Check if there was too many login attempts
if( Confide::isThrottled( $input ) )
{
$err_msg = Lang::get('confide::confide.alerts.too_many_attempts');
}
elseif( $user->checkUserExists( $input ) and ! $user->isConfirmed( $input ) )
{
$err_msg = Lang::get('confide::confide.alerts.not_confirmed');
}
else
{
$err_msg = Lang::get('confide::confide.alerts.wrong_credentials');
}
return Redirect::action('UserController#login')
->withInput(Input::except('password'))
->with( 'error', $err_msg );
}
}
public function confirm( $code )
{
if ( Confide::confirm( $code ) )
{
$notice_msg = Lang::get('confide::confide.alerts.confirmation');
return Redirect::action('UserController#login')
->with( 'notice', $notice_msg );
}
else
{
$error_msg = Lang::get('confide::confide.alerts.wrong_confirmation');
return Redirect::action('UserController#login')
->with( 'error', $error_msg );
}
}
public function forgot_password()
{
return View::make(Config::get('confide::forgot_password_form'));
}
public function do_forgot_password()
{
if( Confide::forgotPassword( Input::get( 'email' ) ) )
{
$notice_msg = Lang::get('confide::confide.alerts.password_forgot');
return Redirect::action('UserController#login')
->with( 'notice', $notice_msg );
}
else
{
$error_msg = Lang::get('confide::confide.alerts.wrong_password_forgot');
return Redirect::action('UserController#forgot_password')
->withInput()
->with( 'error', $error_msg );
}
}
public function reset_password( $token )
{
return View::make(Config::get('confide::reset_password_form'))
->with('token', $token);
}
public function do_reset_password()
{
$input = array(
'token'=>Input::get( 'token' ),
'password'=>Input::get( 'password' ),
'password_confirmation'=>Input::get( 'password_confirmation' ),
);
// By passing an array with the token, password and confirmation
if( Confide::resetPassword( $input ) )
{
$notice_msg = Lang::get('confide::confide.alerts.password_reset');
return Redirect::action('UserController#login')
->with( 'notice', $notice_msg );
}
else
{
$error_msg = Lang::get('confide::confide.alerts.wrong_password_reset');
return Redirect::action('UserController#reset_password', array('token'=>$input['token']))
->withInput()
->with( 'error', $error_msg );
}
}
public function logout()
{
Confide::logout();
return Redirect::to('/');
}
}
This is what the php artisan confide:controller creates for you and then you can do the same for routes which outputs this in the routes.php file for you:
// Confide routes
Route::get( 'user/create', 'UserController#create');
Route::post('user', 'UserController#store');
Route::get( 'user/login', 'UserController#login');
Route::post('user/login', 'UserController#do_login');
Route::get( 'user/confirm/{code}', 'UserController#confirm');
Route::get( 'user/forgot_password', 'UserController#forgot_password');
Route::post('user/forgot_password', 'UserController#do_forgot_password');
Route::get( 'user/reset_password/{token}', 'UserController#reset_password');
Route::post('user/reset_password', 'UserController#do_reset_password');
Route::get( 'user/logout', 'UserController#logout');
In my User.php model I have this setup which is normal:
<?php namespace App\Models;
use Eloquent;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
use Zizaco\Confide\ConfideUser;
use Zizaco\Entrust\HasRole;
class User extends ConfideUser {
use HasRole;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
public function getPresenter()
{
return new UserPresenter($this);
}
/**
* Get user by username
* #param $username
* #return mixed
*/
public function getUserByUsername( $username )
{
return $this->where('username', '=', $username)->first();
}
/**
* Get the date the user was created.
*
* #return string
*/
public function joined()
{
return String::date(Carbon::createFromFormat('Y-n-j G:i:s', $this->created_at));
}
/**
* Save roles inputted from multiselect
* #param $inputRoles
*/
public function saveRoles($inputRoles)
{
if(! empty($inputRoles)) {
$this->roles()->sync($inputRoles);
} else {
$this->roles()->detach();
}
}
/**
* Returns user's current role ids only.
* #return array|bool
*/
public function currentRoleIds()
{
$roles = $this->roles;
$roleIds = false;
if( !empty( $roles ) ) {
$roleIds = array();
foreach( $roles as &$role )
{
$roleIds[] = $role->id;
}
}
return $roleIds;
}
/**
* Redirect after auth.
* If ifValid is set to true it will redirect a logged in user.
* #param $redirect
* #param bool $ifValid
* #return mixed
*/
public static function checkAuthAndRedirect($redirect, $ifValid=false)
{
// Get the user information
$user = Auth::user();
$redirectTo = false;
if(empty($user->id) && ! $ifValid) // Not logged in redirect, set session.
{
Session::put('loginRedirect', $redirect);
$redirectTo = Redirect::to('user/login')
->with( 'notice', Lang::get('user/user.login_first') );
}
elseif(!empty($user->id) && $ifValid) // Valid user, we want to redirect.
{
$redirectTo = Redirect::to($redirect);
}
return array($user, $redirectTo);
}
public function currentUser()
{
return (new Confide(new ConfideEloquentRepository()))->user();
}
}
So from this I can go to the form on /user/create and it outputs the form which means that route is working but on submit I get the No method error.
Can anyone shed some light onto this please?
Thanks
Whenever you type composer-dump autoload, composer recreates a bunch of files which tell it what classes should be registered into the autoloader. classmap autoloading requires you to composer dump-autoload whenever you make new files in a directory being autoloaded. psr-0 autoloading requires you to namespace your files but from then on you don't need to composer dump-autoload except for the first time you define the psr-0 autoloading in your composer.json file.