I'm getting the following error on every view available for the 'guest' user:
Notice: Trying to get property of non-object in /home/fiodorovich/public_html/gisele/library/Federico/Plugin/Acl.php on line 35
the line it's referring to is '$role = $this->_auth->getStorage()->read()->role;' in:
public function preDispatch (Zend_Controller_Request_Abstract $request)
{
$role = $this->_auth->getStorage()->read()->role;
if($role === null) {
$role = self::DEFAULT_ROLE;
}
$action = $request->getActionName();
$controller = $request->getControllerName();
if($this->_acl->has($controller)) {
if(!$this->_acl->isAllowed($role, $controller, $action)) {
$request->setActionName('error');
$request->setControllerName('error');
}
}
}
I know it's just a notice, and that it won't show in production since errors will be disabled... however it's kind of bugging me. So how could I solve this?
Use $this->_auth->hasIdentity() before request data from storage.
if ($this->_auth->hasIdentity()) {
// user is logged in and we can get role
$role = $this->_auth->getStorage()->read()->role;
} else {
// guest
$role = self::DEFAULT_ROLE;
}
Related
A PHP Error was encountered
Severity: Warning
Message: ini_set(): A session is active. You cannot change the session module's ini settings at this time
Filename: Session/Session.php
Line Number: 316
Backtrace:
File: C:\xampp\htdocs\testing\index.php
Line: 315
Function: require_once
<?php
session_start(); //we need to start session in order to access it through CI
class Adminlogin extends CI_Controller {
public function _construct(){
parent::_construct();
//Load form helper library
$this->load->helper('form');
//Load form validation library
$this->load->library('form_validation');
//Load session library
$this->load->library('session');
//Load database
$this->load->model('login_database');
}
//show login page
public function index()
{
$this->load->view('admin_login');
}
//show registration page
public function user_registration_show(){
$this->load->view('admin_signup');
}
//Validate and store registration data in database
public function new_user_registration(){
//Check Validation for user input in SignUp form
$this->form_validation->set_rules('admin_username', 'Username','trim|required|xss_clean');
$this->form_validation->set_rules('admin_password', 'Password','trim|required|xss_clean');
if($this->form_validation->run()== FALSE){
$this->load->view('admin_signup');}
else{
$data = array(
'admin_username' => $this->input->post('username'),
'admin_password' => $this->input->post('password'));
$result = $this->login_database->registration_insert($data);
if($result == TRUE){
$data['message_display'] = 'Registration Successfully !';
$this->load->view('admin_login', $data);
}else{
$data['message_display'] = 'Username already exist';
$this->load->view('admin_signup',$data);
}
}
}
//Check for user login process
public function user_login_process(){
$this->form_validation->set_rules('admin_username','Username', 'trim|required|xss_clean');
$this->form_validation->set_rules('admin_password','Password', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE){
if(isset($this->session->userdata['loggen_in'])){
$this->load->view('Admin/admin_dashboard');
}else{
$this->load->view('admin_login');
}
}else{
$data = array(
'admin_username' => $this->input->post('username'),
'admin_password' => $this->input->post('password'));
$result = $this->login_database->login($data);
if($result == TRUE) {
$username = $this->input->post('username');
$result = $this->login_database->read_user_information($username);
if($result != false){
$session_data = array(
'username' => $result[0]->admin_username,
'password' => $result[0]->admin_password);
//Add user data in session
$this->session->set_userdata('logged_in', $session_data);
$this->load->view('Admin/admin_dashboard');
}else{
$data = array(
'error_message' => 'Invalid Username or Password');
$this->load->view('admin_login',$data);
}
}
}
}
}
?>
Please remove the 1st line session_start(); or change it to..
// session_start(); //I do Not need this as I am using CI Sessions.
You are using CodeIgniters Sessions which you have loaded in your code...
$this->load->library('session');
As an Aside:
You don't need the end ?> in your PHP files where it is the last tag in the file.
I am newbie in mongo db. I want to translate a mongo db code to codeigniter understandable format.
db.demo.find({}, {
"person": 1
});
Here are the relevant code files from my project.
config/mongo.php
$config['mongo_server'] = null;
$config['mongo_dbname'] = 'mydb';
libraries/Mongo.php
class CI_Mongo extends Mongo
{
var $db;
function CI_Mongo()
{
// Fetch CodeIgniter instance
$ci = get_instance();
// Load Mongo configuration file
$ci->load->config('mongo');
// Fetch Mongo server and database configuration
$server = $ci->config->item('mongo_server');
$dbname = $ci->config->item('mongo_dbname');
// Initialise Mongo
if ($server)
{
parent::__construct($server);
}
else
{
parent::__construct();
}
$this->db = $this->$dbname;
}
}
And a sample controller
controllers/posts.php
class Posts extends Controller
{
function Posts()
{
parent::Controller();
}
function index()
{
$posts = $this->mongo->db->posts->find();
foreach ($posts as $id => $post)
{
var_dump($id);
var_dump($post);
}
}
function create()
{
$post = array('title' => 'Test post');
$this->mongo->db->posts->insert($post);
var_dump($post);
}
}
I have changed the Yii UserIdentity class to accept Email from Database as login. Now the problem is that - I am unable to configure this for Admin. Here is my changed code
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('email'=>$this->username));
if($user === NULL)
{
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else
{
if($user->password !== $user->encrypt($this->password))
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id = $user->id;
$this->errorCode=self::ERROR_NONE;
}
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
which works fine for all users. Now, How do I accept for Admin login?
So, I changed my code slightly as below for Admin access, but it does not work for admin. Any help in this regard, will be highly appreciated.
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('email'=>$this->username));
if($user === NULL)
{
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else
{
if($user->password !== $user->encrypt($this->password))
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
if($user->email == 'example#example.com')
$user->id = 'admin';
$this->_id = $user->id;
$this->errorCode=self::ERROR_NONE;
}
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
The error seems to be
$user->id = 'admin';
Where you're attempting to set the value of the primary key to a string. I could be wrong. You could try this:
if($user->email === 'example#example.com') {
Yii::app()->user->setState('role','admin');
}
$this->_id = $user->id;
And then verify an admin in your controllers as an expression -
'expression'=>'Yii::app()->getState("role") == "admin"'
edit
You should add a value to the users table that establishes access levels. Then once the password is verified just put a switch statement in there, ex
switch($user->type) {
case 'admin':
# do this
break;
case 'user':
# do that
break;
}
Forgive my English.
I want to redirect not from action side but from a other function.
controller
public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getEntityManager();
$article = $em->getRepository('MySampleBundle:Article')->find($id);
// TODO:
// Since other actions have the same processing,
// I would like to do check work in other function.
// And when inaccurate,
// I want to make it move from that function to other page.
$this->is_edit_granted($article);
$form = $this->createForm(new ArticleType(), $article);
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
// ...
}
}
return $this->render('MySampleBundle:Article:edit.html.twig', array(
'form' => $form->createView(),
'article' => $article,
));
}
public function is_edit_granted($article)
{
// TODO:
// I check not at the action side but at this place,
// and want to make it move from this function to other page.
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
return $this->redirect( // doesn't work here
$this->generateUrl('home', array(
"id" => $article->getId()
))
);
}
}
I also tried similar code:
use Symfony\Component\HttpFoundation\RedirectResponse;
class SampleController extends Controller
{
// ...
public function editAction(Request $request, $id)
{
// ...
$this->is_edit_granted($article);
// ...
}
public function is_edit_granted($article)
{
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
return new RedirectResponse(
$this->generateUrl('home', array(
"id" => $article->getId()
))
);
}
}
}
but it doesn't work.
It is performing in the environment of Symfony 2.1.2.
How can I manage to achieve that?
Or, is there any better method?
Do something like:
public function editAction(Request $request, $id)
{
// ...
$response = $this->is_edit_granted($article);
if ($response) return $response;
// ...
}
public function is_review_granted($article)
{
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
return new RedirectResponse(
$this->generateUrl('home', array(
"id" => $article->getId()
))
);
}
return null;
}
It is not possible to redirect from the is_review_granted without returning the RedirectResponse form the editAction. So the answer of Carlos Granados is correct.
Another option would be to throw an AccessDeniedException in the is_review_granted method:
public function is_review_granted($article)
{
if (!$article) {
throw $this->createNotFoundException('No article found.');
} else if ( $article->getAuthor() != $this->getUser()->getId() ) {
throw new Symfony\Component\Security\Core\Exception\AccessDeniedException('no acces');
}
}
You could also look to some more in-depth solutions like ACL and SecurityVoters.
I have created a zend form where I have a password and confirm password filed. I am using same form for add and update/edit the database. My code is working fine when I want to add a new password but don't work when I want to edit already existing one.
My form:
$password = new Zend_Form_Element_Password('password');
$password->setRequired(true)
->addFilter('StringTrim')
->addFilter('StripTags')
->addValidator('NotEmpty', false, array('messages'=>'password cannot be empty'))
->addValidator('StringLength', false, array(5, 25, 'messages'=>'password must be 5-30 character'))
->setLabel('Password:');
$this->addElement($password);
$confirmPassword = new Zend_Form_Element_Password('confirmPassword');
$confirmPassword->setRequired(true)
->addFilter('StringTrim')
->addFilter('StripTags')
->addValidator('NotEmpty', false, array('messages'=>'password don\'t match'))
->addValidator(new School_Validate_PasswordConfirmation())
->setLabel('Confirm Password');
$this->addElement($confirmPassword);
my School_Validate_PasswordConfirmation class:
class School_Validate_PasswordConfirmation extends Zend_Validate_Abstract
{
const NOT_MATCH = 'notMatch';
protected $_messageTemplates = array(
self::NOT_MATCH => 'Password confirmation does not match'
);
public function isValid($value, $context = null)
{
$value = (string) $value;
$this->_setValue($value);
if (is_array($context)) {
if (isset($context['password'])&& ($value == $context['password']))
{
return true;
}
} elseif (is_string($context) && ($value == $context)) {
return true;
}
$this->_error(self::NOT_MATCH);
return false;
}
}
When I want to edit other fields other than password the it gives the below error messages. But this messages will only be shown when I enter the user for the first time.
Errors:
password cannot be empty
password don't match
Thanks in advance.
When the form is in edit mode, just remove the validators from the element.
public function someAction()
{
$form = new Application_Form_YourForm();
if ('in edit mode') {
$form->getElement('password')->clearValidators();
$form->getElement('confirmPassword')->clearValidators();
}
if ($this->getRequest()->isPost()) {
$valid = $form->isValid($this->getRequest()->getPost());
if ($valid) {
// ...
} else {
// ...
}
}
}
If you allow someone to change their password by filling in those fields, add an additional check to see if anything is entered into the password field when in edit mode. If they have filled in the password, leave the validators, otherwise remove them.
Hope that helps.