CakeDC Users plugin not reading permissions.php - cakephp

i’m trying to make use of the cakeDC Users-Plugin 8.5.1 in a cakephp 3.8 but all i get is a message ‘you are not allowed to access that location’. I 'm using simple RBAC followed the instruction according the documentation on github. it seems the config/permissions.php is not read because when i write some bad syntax in this file nothing changes - no error messages. instead same behavior ‘you are not allowed …’
Here is what i did:
i used composer to install the plugin.
Since i use cakephp 3.8 the plugin is added in Application.php.
In the AppController.php initialize() i inserted
$config['Auth']['authorize']['Users.SimpleRbac'] = [
//autoload permissions.php
'autoload_config' => 'permissions',
//role field in the Users table
'role_field' => 'role',
//default role, used in new users registered and also as role matcher when no role is available
'default_role' => 'user',
/*
* This is a quick roles-permissions implementation
* Rules are evaluated top-down, first matching rule will apply
* Each line define
* [
* 'role' => 'admin',
* 'plugin', (optional, default = null)
* 'controller',
* 'action',
* 'allowed' (optional, default = true)
* ]
* You could use '*' to match anything
* Suggestion: put your rules into a specific config file
*/
'permissions' => [],
];
For the users table i have my own uprofiles table which contain the columns the plugin needs.
So in my UprofilesController.php i added the code to use the traits which come with the plugin.
In the config/users.php i changed the name of the table to ‘uprofiles’ and the name of the controller to ‘Uprofiles’.
The Auth part in the users.php is
'Auth' => [
'loginAction' => [
'plugin' => 'CakeDC/Users',
'controller' => 'Users',
'action' => 'login',
'prefix' => false
],
'authenticate' => [
'all' => [
'finder' => 'auth',
],
'CakeDC/Auth.ApiKey',
'CakeDC/Auth.RememberMe',
'Form',
],
'authorize' => [
'CakeDC/Auth.Superuser',
'CakeDC/Auth.SimpleRbac',
],
],
What is wrong ? Can someone help me?
I also tried to setup a superuser with the bake tool. That didn’t work.
Error: [BadMethodCallException] Unknown method "generateUniqueUsername" in .../vendor/cakephp/cakephp/src/ORM/Table.php on line 2524
Thank you for help

Related

How to have different dashboards based on roles with cakedc plugins / users & acl

I am using CakeDC Users & ACL plugins in my CakePhp app. I have different roles for my users in my app and I would like to have different dashboards based on roles after login.
I extend the plugin with my own table and controller based on the documentation here, so I have MyUsersController and MyUsersTable which override the initial files of the plugin, UsersController and UsersTable. Everything works fine. I create an event in my events.php file which contains:
use CakeDC\Users\Controller\Component\UsersAuthComponent;
use Cake\Event\Event;
use Cake\Event\EventManager;
EventManager::instance()->on(
UsersAuthComponent::EVENT_AFTER_LOGIN,
['priority' => 99],
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-f9effb2de026') //the id of my client role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'MyUsers', 'action' => 'index', '_full' => true, 'prefix' => false];
}
}
);
But it seems like the override is not working because I have an error:
Error: CakeDC/Users.MyUsersController could not be found.
In my URL I have /users/my-users instead of /my-users and I don't know why. I have test with a template file which is include in the plugin and the Users controller like this:
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-
f9effb2de026') //the id of role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'Users', 'action' => 'profile';
}
And it works. My URL redirect after login as a client is /profile.
Could someone help me to understand? Please tell me if it's not clear enough and if it's missing parts of codes that might be important to understand my problem.
I specify that I am beginner with Cake.
Your custom controller doesn't live in the CakeDC/Users plugin, hence you must disable the plugin key accordingly, so that the correct URL is being generated (assuming your routes are set up correctly) that connects to your controller, like this:
[
'plugin' => null,
'controller' => 'MyUsers',
'action' => 'index',
'_full' => true,
'prefix' => false
]
That would for example match the default fallback routes, generating a URL like /my-users.
See also:
Cookbook > Routing > Creating Links to Plugin Routes

CakePHP 3.* Prefix routing error

I made 3 tables namely Roles, Users, and Blogs. Roles have a 1 to many relationship with Users having a role_id foreign key, and likewise, Users have a one to many relationship with Blogs having the user_id foreign key. I initially baked all 3 users and everything was fine. I then decided to try prefixing admin for Roles.
Router::prefix('admin', function ($routes) {
$routes->connect('/roles', ['controller' => 'Roles', 'action' => 'index]
)};
I made a folder inside the Controller folder (Controller > Admin) and put my RolesController there. I changed the namespace of my RolesController to namespace App\Controller\Admin. I also adjusted the file location of my Roles View files by putting it inside an Admin Folder (Admin > Roles > add.ctp, edit.ctp, index.ctp, view.ctp).
Everytime I try to access localhost:8765/admin/roles, I get an error message that says:
Error: A route matching "array ( 'action' => 'add', 'prefix' => 'admin', 'plugin' => NULL, 'controller' => 'Roles', '_ext' => NULL, )" could not be found. None of the currently connected routes match the provided parameters. Add a matching route to config/routes.php
The passed context was:
[
'_base' => '',
'_port' => (int) 8765,
'_scheme' => 'http',
'_host' => 'localhost',
'params' => [
'pass' => [],
'controller' => 'Roles',
'action' => 'index',
'prefix' => 'admin',
'plugin' => null,
'_matchedRoute' => '/admin/roles',
'_ext' => null
]
I am fairly new to cakephp, could someone please help me with this problem? Any advise would be much appreciated.
By adding $routes->connect('/roles', ['controller' => 'Roles', 'action' => 'index] you're only routing /admin/roles (index action) but not any other action of Roles.
If you only plan of having Roles in Admin then you should only add this line in your Router::prefix block:
$routes->connect('/roles/:action/*', ['controller' => 'Roles']);
Otherwise you should add a default fallback (as the / scope has) by adding this line: (note that it can be the only line in the Router::prefix block):
$routes->fallbacks(DashedRoute::class);
Your block will then look like that:
Router::prefix('admin', function ($routes) {
$routes->fallbacks(DashedRoute::class);
)};
See https://book.cakephp.org/3.0/en/development/routing.html#fallbacks-method for more informations about fallbacks methods in CakePHP.

CakePHP 3.x - File validators on upload always failing

I am working on an image upload. I am trying to do the image verification in the model (like it should, right?), however I can't get the validation to work.
I put the following in src/Model/Table/CommentTable:
public function validationDefault(Validator $validator)
{
//...
$validator->add('photofile', 'upload', [
'rule' => ['uploadedFile', ['maxSize' => 1048576, 'optional' => true, 'types' => ['image/*']]],
'message' => 'Not a valid file'
]);
//...
}
For testing my controller looks like (I hard-coded an existing file):
$comment = $this->Comments->newEntity([
'body' => $data['body'],
'bin_id' => $bin_id,
'user_id' => $this->Auth->user('id'),
'photofile' => 'C:/Users/Robert/Downloads/test.jpg'
]);
This file is only a couple of bytes, yet after debugging $comment is shows an error in 'photofile':
'[errors]' => [
'photofile' => [
'upload' => 'Not a valid file'
]
],
So why is the validator always failing? Am I using it correctly?
Well, it's not an uploaded file, so that's generally the expected behavior. Also a string isn't supported as a valid value at all, the value must either be a file upload array, or as of CakePHP 3.4, an object that implements \Psr\Http\Message\UploadedFileInterface.
For file upload arrays, the uploadedFile validation rule provided by CakePHP will utilize is_uploaded_file(), which will fail for files that haven't actually been uploaded, and you cannot emulate them.
As of CakePHP 3.4 you can use UploadedFileInterface objects as already mentioned. CakePHP requires \Zend\Diactoros\UploadedFile which provides an implementation that you could utilize for testing purposes, like:
$file = 'C:/Users/Robert/Downloads/test.jpg';
$comment = $this->Comments->newEntity([
'body' => $data['body'],
'bin_id' => $bin_id,
'user_id' => $this->Auth->user('id'),
'photofile' => new \Zend\Diactoros\UploadedFile(
$file,
filesize($file),
\UPLOAD_ERR_OK,
pathinfo($file, \PATHINFO_BASENAME),
'image/jpeg'
)
]);
However while this will pass validation, you won't be able to move that file using UploadedFile::moveTo(), as it uses move_uploaded_file(), which again only works with files that have actually been uploaded.
Also regex validation of MIME types only works when passed as a string (this currently isn't documented), and it must be a valid regex including delimiters, like
'types' => '#^image/.+$#'
Alternatively specify the exact types as an array, ie
'types' => ['image/jpeg', 'image/png', /* ... */]
See also
Zend Diactoros API > UploadedFile
CakePHP API > \Cake\Validation\Validation::uploadedFile()

CakePHP 3.4: set up an email transport only for tests

I'm trying to write tests for an action that sends an email, using get() / posts() methods provided by the IntegrationTestCase class.
The code is something like this:
$this->getMailer('User')
->set('someVarName', 'someVarValue)
->send('forgotPassword', [$user]);
Normally this code works.
But by testing, I get this error:
1) MeCms\Test\TestCase\Controller\UsersControllerTest::testForgotPassword
BadMethodCallException: Cannot send email, transport was not defined. Did you call transport() or define a transport in the set profile?
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/Mailer/Email.php:2049
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/Mailer/Mailer.php:252
/home/mirko/Libs/Plugins/MeCms/src/Controller/UsersController.php:213
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/Controller/Controller.php:440
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php:119
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php:93
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/Routing/Dispatcher.php:60
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/TestSuite/LegacyRequestDispatcher.php:61
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestCase.php:426
/home/mirko/Libs/Plugins/MeCms/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestCase.php:360
/home/mirko/Libs/Plugins/MeCms/tests/TestCase/Controller/UsersControllerTest.php:345
I've been looking a bit, but I did not understand how to set up a transport only for tests.
Thanks.
I didn’t came across such requirement, but the following should work.
In your /tests/bootstrap.php define a constant, so we can tell if we are in a testing environment:
define('_TEST', true);
// important: define above requiring the /config/bootstrap.php
require dirname(__DIR__) . '/config/bootstrap.php';
In /config/bootstrap.php check against the constant after the default app config file is loaded:
Configure::load('app', 'default', false);
// load an additional config file `/config/app_testing.php` in testing environment
if (defined('_TEST') && _TEST === true) {
Configure::load('app_tests');
}
Finally create the config file /config/app_tests.php for testing and overwrite some of the default config values:
<?php
return [
'Email' => [
'default' => [
'transport' => 'gmail',
'log' => true
]
],
'EmailTransport' => [
'gmail' => [
'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'username' => 'GoogleMailUserName',
'password' => 'GoogleMailPassword',
'className' => 'Smtp'
]
]
];

The requested URL /drupalhr/drupal/employee/add/ was not found on this server

I have created a custom module in drupal with entities. I have installed the entity api module. I have created my database schema with just two columns (employee_id, first_name) through the help of employee_management.install file (where as employee_management is my custom module name) and employee is my entity name.
I have also written the requisite functions employee_management.module but still it shows me the error , Whenever i tried to add a new entity in the admin/structure/employee it shows me the following error: "Not Found".
The requested URL drupal/employee/add/ was not found on this server.
function employee_management_entity_info() {
$employee_info['employee'] = array(
// A human readable label to identify our entity.
'label' => t('Employee Entity'),
// The controller for our Entity - extends the Drupal core controller.
'controller class' => 'EmployeeController',
// The table defined in hook_schema()
'base table' => 'employee',
// Returns the uri elements of an entity
'uri callback' => 'employee',
// Fieldable that we can attach fields to it - the core functionality will
// do the heavy lifting here.
'fieldable' => TRUE,
// The unique key of our base table.
'entity keys' => array(
'id' => 'employee_id',
),
// FALSE disables caching - caching functionality is handled by Drupal core
'static cache' => TRUE,
// Attach bundles - i.e. alternative configurations of fields associated with a main entity.
'bundles' => array(
'employee' => array(
'label' => 'Employee',
// Information below is used by the Field UI - they "attach" themselves here and lets us
// do the standard field management that all the core entities enjoy.
'admin' => array(
'path' => 'admin/structure/employee/add',
'access arguments' => array('administer employee entities'),
),
),
),
// View modes allow entities to be displayed differently based on context. We simply have one option
// here but an alternative would be to have a Full and Teaser mode akin to node.
'view modes' => array(
'full' => array(
'label' => t('Full'),
'custom settings' => FALSE,
),
)
);
return $employee_info;
}
EDIT
function employee_uri($employee) {
return array(
'path' => 'employee/' . $employee->employee_id,
);
}
And here is the complete list of function in the file employee_management.module
You don't automagically get the route and form to create your entity, you'll have to implement that yourself. See hook_menu and this guide.

Resources