I am working in this project which is left by some other person to me.
The database of this project has been moved from one location to another. Moving the database is done by the owner. This caused one function to stop working which is the "delete" function for records.
For my development enviroment I moved the database locally, than it suddenly works. Which make me believe that there is something wrong with sending a delete request to the server.
The code looks like this:
if ($this->RemovedDuty->save($duty['Duty'])) {
if ($this->Duty->delete($duty_id)) {
$this->Session->setFlash('This duty is removed', 'default', array('class' => 'message success'));
return true;
} else {
$this->Session->setFlash('This duty could not be removed.', 'default', array('class' => 'message error'));
return false;
}
} else {
$this->Session->setFlash('There is something wrong with backing up the data', 'default', array('class' => 'message error'));
return false;
}
}
How can I go about troubleshooting my problem?
Have you checked, whether your database user has got the privilege to delete records for the new server.
Are you sure about your models? I see that you're saving in RemovedDuty model and deleting in Duty model. Make sure your models are correct.
Also check if the models are referencing correct tables.
Cheers!
Related
I'm currently developping a new website for an artists organization. The administrator role is allowed to create accounts and some other node content, the created accounts have the same default role called "artisan". Administrators are Artisans as well. Artisans can create and edit their own content. Both administrators and artisans should be able to edit user profile (all for admin, only their own for artisan). The fact is admin can create a user but nobody (except user1) can save user profile after edit (but it works great for other nodes). Permissions have been scanned multiple times. I have been searching everywhere with no success, what am I missing ? I made very few changes, the only related code I wrote is the following :
<?php
function canardesign_system_form_alter(&$form, &$form_state, $form_id){
global $user;
switch ($form_id){
case 'oeuvre_node_form':
$form['actions']['submit']['#submit'][] = 'canardesign_system_oeuvre_redirect';
if (in_array('artisan', array_values($user->roles))){
$form['field_auteur']['#type']= 'hidden';
$form['field_auteur']['und']['#default_value']= $user->uid;
}
break;
case 'user_profile_form':
if (in_array('artisan', array_values($user->roles))){
$form['actions']['submit']['#submit'][] = 'canardesign_system_user_profile_form_submit';
}
break;
}
}
function canardesign_system_oeuvre_redirect($form, &$form_state) {
$type=$form['#node']->type;
if(isset($type))
{
$node = node_load($form_state['nid']);
$uid=field_get_items('node', $node, 'field_auteur')[0]['target_id'];
$form_state['redirect'] = 'oeuvres/'.$uid;
}
}
function canardesign_system_user_profile_form_submit($form, &$form_state) {
drupal_goto('artisans');
}
/*default role when administrator (who is artisan as well) creates an account*/
function canardesign_system_user_insert(&$edit, $account, $category) {
global $user;
if (in_array('artisan', array_values($user->roles))){
$account->role = 'artisan';
}
}
?>
Thank you for your help.
I'm not sure if this is the cause of your issue, but calling drupal_goto() inside a submit hook is definitely problematic. It essentially shorts out the handling of the form.
This may be causing the issue by preventing other necessary code from executing.
You should instead set the redirect key of $form_state to the destination you would like the user to end up on.
Once the form handling is complete, Drupal will send the user there.
function canardesign_system_user_profile_form_submit($form, &$form_state) {
$form_state['redirect'] = 'artisans';
}
Iam writing an application with cakephp where i will have admin and agents where they can login to the system. Admin will have different layout from the agents. I have already create the the users table where i added a role field (admin,agent) ,i added the prefixes in core.php
Configure::write('Routing.prefixes', array('admin','agent'));
I managed to create the login and the logout for admin, but still iam confused how i should proceed with the rest. For Example i dont understand how beforeFilter() and isAuthorized() functions works. How i can check if user has access to that function or not. Also the redirections if a someone try to access this page domain.com/admin to be redirected to admin/login page .
Thanks.
Use the beforeFilter() to control access to each action, the below example will only allow access to the view and index action - any other action will be blocked :
$this->Auth->allow('view', 'index');
if you want to allow access to all the actions in your controller , try this in your before filter:
$this->Auth->allow();
To control who has access to what you could use a simple function in your app controller like so:
protected function _isAuthorized($role_required) {
if ($this->Auth->user('role') != $role_required) {
$this->Session->setFlash("your message here...");
$this->redirect("wherever you want the user to go to...");
}
}
In your controller action, eg. admin_delete on the first line you would do the following:
$this->_isAuthorized('admin');
Finally the redirect works like so:
$this->redirect(array('controller' => 'home', 'action' => 'dashboard'));
if you are redirecting within the same controller simply do the following:
$this->redirect('dashboard');
Hope this helps.
What i usually do is extend my App controller into an AdminAppController and SiteController , in the AdminAppController I have the following code in my beforeFilter:
$controller = strtolower($this->params["controller"]);
$action = strtolower($this->params["action"]);
$crole = $this->Auth->user("role");
$allowed = false;
$roles = array(
"all"=>array("user#login","user#register","user#forgot"),
"admin"=>array("pages#index","pages#view")
);
if(in_array($controller."#".$action,$roles["all"])){
$allowed = true;
}else{
if(in_array($controller."#".$action,$roles[$crole])){
$allowed = true;
}
}
if($allowed==false){
$this->setFlash("Access denied message...");
$this->redirect("...");
}
Don't know if this is the best practice but it works just fine. I normally hate CakePHP's built in Authorization system.
To check for allowance per role, I think it's best to use the Auth->allow([...]) in a per controller basis.
I find it best to check in Controller::beforeFilter() with a:
switch ($role) {
case 'admin':
$this->Auth->allow(...); //Allow delete
//notice no break; statement, so next case will execute too if admin
case 'manager':
$this->Auth->allow(...); //Allow edit
case default:
$this->Auth->allow(...); //Allow index
}
While you can check in AppController, I don't want to remember to change two files when I edit just one.
Please bear with me, as I'm a programming/cakephp noob, but I do not know how to restrict the user from access to other user data. When a user logs in, they get a dashboard of their listings (which come from several models....restaurants, hotels, golf courses, images for each listing, location information, coupons, etc..).
Depending on the model/controller, I could have user '3' (who has hotel listings) type into the browser bar /restaurants/edit/1 and edit the restaurant information of user '17' who has a restaurant with ID='1'. Worse, they can even access /users/dashboard/17. How do I limit a user to only access their own data? I was hoping there was some sort of 'beforeAllow()' part of the AuthComponent I could use in the AppController that checks user id beforehand and kicks them back out to their dashboard if they try to perform a CRUD action on other users' data.
Even if I was using ACL (I know I should but it's frankly a little too over my head at this stage of learning), I'd still have to know the right code to limit user access, correct?
Below is my AppController:
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'view'),
'logoutRedirect' => array('controller' => 'docs', 'action' => 'index'),
'authError' => 'Sorry, you are not authorized to view this page.'
)
);
function beforeFilter() {
$this->Auth->userModel = 'User';
$this->Auth->allow('join_now','debug','index', 'condos', 'houses', 'hotels_and_motels', 'print_all_coupons', 'print_coupon', 'search', 'golf', 'charters', 'events', 'nightlife', 'shopping', 'visitors_info', 'contact_us', 'view', 'results');
}
}
and here is a sample edit function (the edit function from my UnitsController):
function edit($id) {
$this->set('title', 'Edit your property');
$this->Unit->id = $id;
if (empty($this->request->data)) {
$this->request->data = $this->Unit->read();
} else {
if ($this->Unit->saveAll($this->request->data)) {
$this->Session->setFlash('Your property has been updated.', 'success');
}
}
}
I will say that every one of my db tables has a user_id field so the logged in user can be matched with the user_id of each model.
I thought that this SO question was what I was looking for but they ended up getting off on a tangent in it and never answered the original question the user asked.
If you where using cakes acl and auth, then no, you wouldn't have to write a bunch of code, checking the user ids for each action, but you'd have to write the code to tie together the acl's. You'd tell the Component that your controller and actions require acl privelages. And it doesnt the look ups in the aros and acos tables to make sure that your object requesting the content has the proper permissions.
I HIGHLY recommend you take a look at the tutorial and figure out how to get it to work
If you don't go that route, then you will have to add in the checking to every action that loads dependent content. Basically you'll, when a action is requested, you'll feature the object, then get the user associated to that object and check to see if the id of the user the same as the id as the requesting the object.
if ( $this->Unit->User->uid != $this->Session->User->uid ) {
throw new NotFoundException('Could not find that Unit');
} else {
...
}
The other thing you can do, for pages that are the same, but customized, is not use the url /user/dashboard/17 and instead just use /user/dashboard then in the dashboard action, pull the user id from the session data and load the profile for the user that is authenticated
I think you will need to use CRUD authorization for adding EditOwn actions. The answer described in CakePHP ACL Database Setup: ARO / ACO structure? handles much of the logic that you need.
Please note that the solution is still not complete and you will get access to actions that can render other users' data. Example: scaffold 'index' methods. To restrict access to other users' data here, you can modify the query to add filters based on User ID that you get from Session.
I have started learning cakePHP and now I am facing the following problem. How can allow my users to change their profile (their info in the DB).
This is my model -> http://bin.cakephp.org/view/798927304 I use these validations when someone tries to register .
This is my method for editing profiles: http://bin.cakephp.org/view/841227800
First I check does the user have the permission to edit this profile (is the profile his own).
Then get the desired id and try to save the request->data... But unfortunately without success.
And last this is my view -> http://bin.cakephp.org/view/1798312426
The only things I want to make are:
-Change their email (if they add new email)
-Change their social profiles (if the add them)
-Change their password (if they add it)
Can you guide me to do these things?
Thanks in advance!
Typically, when you call a save, as in:
$this->User->save($this->request->data)
The data in $this->request->data is cleared by default. In your edit method, you have an if statement below that is using the same save again.
The default functionality which I assume you have copied from a cakebaked edit method typically does the save and uses the returned logic to power that if statement. The second time you call it, you might be getting a false returned, which is likely skipping over that if statement.
To debug this, I suggest several of these in different locations:
debug($this->request->data);
Also, debug printouts are cleared on redirect, so in the mean time, you may want to comment out the redirect inside the if statement like so:
if ($this->User->save($this->request->data)) {
$this->Session->setFlash('Успешно променихте профила си.', 'success_message');
//$this->redirect(array('action' => 'profile'));
}
if($this->Auth->user() && $this->Auth->user('id') == $id) {
$this->User->read(null, $id);
$this->User->set(array(
'email' => $this->data['User']['email'],
'password' => $this->data['User']['password'],
'social_profile' => 'bla bla'
));
$this->User->save();
// etc
may do what you're after.
more # http://book.cakephp.org/view/1031/Saving-Your-Data
I want to prevent banned users from logging in to the site and give them a message that they are banned. I tried to use isAuthorized() for this but it allows the user to login and only after that denies him permission to the unauthorized actions.
So, basically I want to know where to put the condition that would check if the user table as banned = true, before the login process takes place. Right now my login function is empty as its being automatically controlled by the Auth Component.
Finally, I found a solution by going through the API. I wonder if anyone has used this ever, cause nobody pointed me to this, or maybe I wasn't clear enough. Anyways, to add a condition to the login process you just have put it in the variable $this->Auth->userScope
So, to check if a user is banned I just added this line to the beforeFilter() in my AppController,
$this->Auth->userScope = array('User.banned'=>0);
Hope this helps someone.
Alternatively to:
$this->Auth->userScope = array('User.banned'=>0);
This can be done when you include your Auth Component. This probably saves some tiny amount of overhead as $this->Auth->userScope isn't called every time a controller is parsed.
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish',
'scope' => array('User.banned' => 0)
)
),
'authorize' => array('Controller')
)
);
If you have the whole Auth system already up and running, why don't you just follow the KISS principle and revoke their password or alter there username? If they are not longer able to authenticate with your system as they could earlier they should be able to deduce that they are banned.
If that doesn't suffice, then additionally you could add the code below.
function login() {
if ($this->Session->read('Auth.User')) {
$this->Session->setFlash('You are alreadylogged in!~~~~~~~~~~~');
}
$this->Session->setFlash('You have been banned!');
$this->redirect(array('controller'=>'users','action'=>'index'));
}
Edit 1: For a more dynamically approach like you pointed out in your comment, you could check the is_banned column of the user record under concern in your UsersController::beforeFilter() and set your flash message accordingly. Also make a redirect based on the outcome of $this->Session->read('Auth.User.is_banned'). Maybe you want to have a look at the output of <?php debug $this->Session->read('Auth.User) ?> before attacking your problem.
Edit 2: My fault. You could store the is_banned somewhere in the Session via $this->Session->write(...). After you read an is_banned = true you can log the user out.
you have to use:
/** Function is executed after the login*/
function isAuthorized() {
return true;
}
where you can check if the user is banned or no. i.e.
/** Function is executed after the login*/
function isAuthorized() {
if($this->Auth->user('banned') == 1){ //column banned should be in the users table
$this->Session->setFlash('You have been banned!');
return false;
}
return true;
}
I believe this is the correct way.
Having read your last comment on Nik's way, I think that you could just refine your original solution by logging the user out manually via $this->Auth->logout() at the appropriate place in your code (followed by a redirect). This way it should look like he/she never logged in.