CakePHP check or add user id to posts - php

I have the following two actions in my controller:
function add()
{
if (!empty($this->data))
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been saved.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
function edit($id = null)
{
$this->Favour->id = $id;
if (empty($this->data))
{
$this->data = $this->Favour->read();
}
else
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been updated.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
1) I want to be able to add the logged in user id to the add action so that the new post is created with that user as its author id (their is a foreign key in the db table). I'm not sure how to talk to fields within the controller itself.
2) And for the edit action I want to make it so that only the author can edit the post so for example user 200 creates post 20 but user 100 cannot edit this post because his id is not 200! I'm not using ACL for my app but just simple authentication.
I've thought about doing a simple if statement in the action like:
function edit($id = null)
{
$this->Favour->id = $id;
$this->Favour->user_id = $user_id;
if($this->Auth->user('id') != $user_id)
{
$this->Session->setFlash('You do not have permission to edit that favour!');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
else
{
if (empty($this->data))
{
$this->data = $this->Favour->read();
}
else
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been updated.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
Would this be correct? BUT how do I get the user id from the favour?

function add() {
if (!empty($this->data)) {
$this->data['Favour']['user_id'] = $this->Auth->user('id');
if ($this->Favour->save($this->data)) {
//etc
This code assumes:
Your user is logged in
the user can access the add function
You are storing the id value of the logged in user in the field id
You have a foreign key in Favours table called user_id that matches the data type of the user id
As for edit; couple ways of achieving it.
I'd do:
function edit($id) {
$this->Favour->id = $id;
$favour_author = $this->Favour->field('user_id');
// get the user of this post
if($this->Auth->user('id') != $favour_author) {
$this->Session->setFlash('You do not own this post.');
$this->redirect('/someplace');
}
if (empty($this->data)) {
$this->data = $this->Favour->read();
}
// carry on.

If you use Auth Component, you can access the logged-in user record in $this->Auth->user() in controller. So to access the id: $this->Auth->user('id'). If you write your own authentication, it's up to you.
how to talk to fields within the controller itself.
What do you mean?

Related

php cake Auth inside class

I need to check if a user is existing in the mgrUser table. now the propblem is the controller is in the adminController while the model is in the mgrUserModel. how do i use Auth for this? Thats the reason why I made a generic login code.
public function login() {
// if ($this->Auth->login()) {
// return $this->redirect($this->Auth->redirectUrl());
// }
// $this->Flash->error(
// __('Username ou password incorrect')
// );
//since the model is in a different view, I needed to includ the mgrModel and create a generic login
//will revamp the code to fit the built in Aut code for php cake
if(isset($_POST['submit'])) {
$User_ID = htmlspecialchars($_POST['user_id']);
$Pass = htmlspecialchars($_POST['pass']);
try {
$mgrUserModel = new MgrUser();
$isValid = $mgrUserModel->find('first', array(
'conditions' => array("user_id" => $User_ID)
));
if($isValid != null){
if (($isValid['MgrUser']['pass']) == $Pass) {
//this doesnot work
$this->Auth->allow();
$this->redirect($this->Auth->redirectUrl());
}
else{
}
}
} catch (Exception $e) {
//echo "not logged in";
}
// this echo will show the id and pass that was taken based on the user_id and pass that the user will input
//for testing only
// echo $isValid2['MgrUser']['id'];
// echo $isValid2['MgrUser']['pass'];
}
}
You need double == to compare things,
function checkMe()
{
if($user == 'me'){
$this->Auth->allow('detail');
}
}
what you did was assign "me" string to variable $user which always returns true because assignment was possible
Anyway you should use it in beforeFilter which is running before every action from this controller, which makes much more sense
public function beforeFilter() {
parent::beforeFilter();
if($user == 'me'){
$this->Auth->allow('detail');
}
}
the Auth component could be configured to read the user information via another userModel (The model name of the users table). It defaults to Users.
please consult the book for appropriate cakephp version: https://book.cakephp.org/3.0/en/controllers/components/authentication.html#configuring-authentication-handlers

Yii: Getting the role of logged in users and showing content according to role

I want to get the roles of the registered users and show the content to the registered users according to their roles.
I have two users right now.
admin
user(authenticated)
The thing i am trying to do is that when the admin logs in via "webapp/user/login" a sidebarwidget which i have already made should be shown upon login and when the user(authenticated) gets logged in, the user(authenticated) should only be able to see the index.php page.
I am using Yii users and rights. I have looked around and found this piece of code which is for getting the role of the logged in user but I dont know where to place this piece of code to get the output.
Below are two pieces of codes, please do tell me which one will be more useful.
if($user = Users::model()->findAll()) {
foreach($user as $id => $user) {
if(!$user->checkAccess('Authenticated')) {
unset($user[$id]);
}
}
$users = array_values($user); // to reset indices (optional)
}
and this is another piece of code which i have found.
$command = Yii::app()->db->createCommand("SELECT * FROM `authassignment` WHERE userid={$user->id}");
$results = $command->queryAll();
$roles = array();
foreach ($results as $result)
{
$roles[] = $result['itemname'];
}
$this->setState('roles', $roles);
From what I have done following tutorials, here is a proposal.
The authentication can take place in file protected/components/UserIdentity.php :
public function authenticate($native=false){
$record=User::model()->findByAttributes(array('username'=>$this->username));
//can provide function "same" if needed - found it here:
//http://codereview.stackexchange.com/questions/13512
if($record!==null&&$this->same($record->password,crypt($this->password,$record->password)){
$authRoleName=Role::model()->findByAttributes(array('id'=>$record->role_id))->name;
$this->setState('role_name', $authRoleName);
$this->errorCode = self::ERROR_NONE;
}else{
$this->errorCode=self::ERROR_UNKNOWN_IDENTITY;
}
return !$this->errorCode;
}
In this case the several roles (admin, mobile, user, etc) are stored in db (table roles) and each user model has a role_id.
I assume the SiteController does the login (file protected/controllers/SiteController.php):
public function actionLogin()
{
$model=new LoginForm;
// if it is ajax validation request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login()){
$this->redirect(Yii::app()->user->returnUrl);
}
}
// display the login form
$this->render('login',array('model'=>$model));
}
File protected/models/LoginForm.php:
class LoginForm extends CFormModel
public $username;
public $password;
public $rememberMe;
private $_identity;
public function authenticate($attribute,$params)
{
if(!$this->hasErrors())
{
$this->_identity=new UserIdentity($this->username,$this->password);
if(!$this->_identity->authenticate())
$this->addError('password','False username or password.');
}
}
public function login()
{
if($this->_identity===null)
{
$this->_identity=new UserIdentity($this->username,$this->password);
$this->_identity->authenticate();
}
if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
{
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login($this->_identity, duration);
return true;
}
else
return false;
}
In view you could do a role based decision making, like the example below in file protected/views/site/index.php :
<?php
$userModel =User::model()->findByAttributes(array('id'=>Yii::app()->user->getId()));
if($userModel){
if(Yii::app()->user->getState('role_name') == 'admin'){
$this->renderPartial(
//...
);
}else{
//...
}
}
Moreover, if RBAC is on your mind, and you manage to have a proper protected/data/auth.php (there are ways for this, I use command "./protected/yiic rbac" after creating file protected/commands/RbacCommand.php - I can post this latter file if needed) then in any place in your code you simply:
if(Yii::app()->user->checkAccess('admin')){
//staff for admins
}
Also, in this case, you could set the rights of whole actions in controller's function accessRules() by issuing roles instead of usernames:
public function accessRules()
{
return array{
array('allow',
'actions'=>array('index', 'index2', 'view','create','update','getRecordDetails', 'getTotalCount'),
'roles'=>array('admin'),
),
);
}

Saving user ID to database using CodeIgniter

I am trying to create an application with which users can enrol on to a course. To enrol a user has to be approved by the admin. A user will select a course by clicking on a course,then the course ID and the user ID should get saved in a database. However I can't get the user ID to save in a database. I have added the user ID as a part of the session. So how can I save the user ID which is now in the session?
Here is the model:
public function select_course()
{
$data['users_id']=$this->input->post($this->session->userdata('users_id'));
$query =$this->db->insert('gp_approval_course',$data);
if ($query)
{
return true;
}
else
{
return false;
}
}
Here is the controller:
public function add_course()
{
$this->load->model('model_users');
if ($this->model_users->select_course())
{
echo "You have selected a course to enroll on to!";
echo ($this->session->userdata('users_id'));
return true;
}
else
{
echo "Database problem";
return false;
}
}
change
$data['users_id']=$this->input->post($this->session->userdata('users_id'));
to
$data['users_id']=$this->session->userdata('users_id');
$data['course_id'] = $this->input->post('your_course_id_var');

CakePHP: sending latest user id to admin's create_employee view

I am trying to send the latest user's id from UsersController to AdminController whose add_employee() action creates a new employee. My users and employees table are separate and what I want to do is when Admin creates a new user its entry go into users table. Then he opens create employee form and the latest user id will be assigned to the new employee the admin is creating. So when admin will open create new employee form the latest user id will be shown in the form.
My UsersController has this code for sending latest user it to AdminsController:
public function get_latest_user_id()
{
$content = $this->User->query("SELECT id FROM users ORDER BY id DESC LIMIT 0,1");
$this->set('latest_user', $content);
}
AdminsController page's add_employee contains this code:
public function add_employee()
{
$this->loadModel('Employee');
$this->set('latest_user', $this->requestAction('/Users/get_latest_user_id'));
if ($this->request->is('post'))
{
$this->Employee->create();
if ($this->Employee->save($this->request->data))
{
$this->Session->setFlash(__('The employee profile has been saved.'));
return $this->redirect(array('action' => 'list_of_employees'));
}
else
{
$this->Session->setFlash(__('The employee profile could not be saved. Please, try again.'));
}
}
}
So UserController's get_latest_user_id function sends latest user id to add_employee function of AdminController. There latest_user is set to latest user id so that when add_employee view is called it is there. But it is not showing. So I want to know that am i doing it right? Please help and thanks.
In add_employee.ctp I am displaying it like this:
echo $latest_user['User']['id'];
Move get_latest_user_id to the User model
public function get_latest_user_id()
{
$user = $this->query("SELECT id FROM users ORDER BY id DESC LIMIT 1");
if (empty($user)) {
return 0;
}
// return only the Id
return $user[0]['users']['id'];
}
In the controller:
public function add_employee()
{
$this->loadModel('Employee');
$this->loadModel('User');
$this->set('latest_user', $this->User->get_latest_user_id());
if ($this->request->is('post'))
{
// ....
}
}
cornelb is right that you should move the method to your User model. Although a more Cake-ish approach would be to use a find('first'), rather than doing a direct query():
// app/Model/User.php
public function getLatest() {
// Get the latest user
$user = $this->find('first', array(
'fields' => array('id'), // Only interested in id? Use this.
'order' => array('User.id' => 'DESC')
));
if (!empty($user)) {
return $user['User']['id'];
} else {
// Nothing was returned, this is very awkward
throw new NotFoundException(__('No users found!'));
}
}
And in your controller:
// app/Controller/AdminsController.php
public function add_employee() {
$this->loadModel('User');
$this->set('latestUser', $this->User->getLatest());
// ...
}

CakePHP Security - Prevent Form Injection

I currently have 1 table, Users which looks like this
|**id**|**username**|**password**|**role**|**email**|
I'm using CakePHP's form helper to automatically fill in editable form fields. I'm creating an edit page in which users can change there username/password/email, but should NOT be able to change their role. I'm currently checking to make sure the user hasn't injected a role POST field into the request and was wondering if there is any better way to do this? It's trivial in this scenario with such a small table, but I can see this becoming tiresome on fields/tables with a large amount of columns. My current edit action looks like this.
public function edit($id = null)
{
$this->User->id = $id;
if(!$this->User->exists())
{
throw new NotFoundException('Invalid user');
}
$userToEdit = $this->User->findById($id);
if(!$userToEdit)
{
throw new NotFoundException('Invalid user');
}
if($this->getUserRole() != 'admin' && $userToEdit['User']['owner'] != $this->Auth->user('id'))
{
throw new ForbiddenException("You do not have permission to edit this user");
}
if($this->request->is('post') || $this->request->is('put'))
{
//Do not reset password if empty
if(empty($this->request->data['User']['password']))
unset($this->request->data['User']['password']);
if(isset($this->request->data['User']['role']))
unset($this->request->data['User']['role']);
if($this->User->save($this->request->data))
{
$this->set('success', true);
}
else
$this->set('success', false);
}
else
{
$this->request->data = $this->User->read();
//Prevent formhelper from displaying hashed password.
unset($this->request->data['User']['password']);
}
}
The third parameter of save() method lets you to define the list of fields to save. Model::save() docs
$this->User->id = $this->Auth->user('id');
$this->User->save($this->request->data, true, array('username', 'email'))

Categories