2

I'm currently coding a blog to get experience with php in which I can log in. In the table:

user( id, username, password, permission)

there is one user that has the permission "admin", every other user has the permission "normal".

I want that only an admin can edit posts, so I need to find out what permission the currently logged in user has. I tried to do it with Sessions, but somehow I didn't manage to get it work.

This is the query in the UserRepository.php in which I interact with the db

public function isAdmin($username)
{
  $table = $this->getTableName();
  $model = $this->getModelName();

  $stmt = $this->pdo->prepare("SELECT `permission` FROM `{$table}` WHERE username = :username");
  $stmt->execute(['username' => $username]);

  $stmt->setFetchMode(PDO::FETCH_CLASS, $model);
  $isAdmin = $stmt->fetch(PDO::FETCH_CLASS);

  return $isAdmin;
} 

Here is the part of a function from the LoginService.php in which I call the upper function in the repository:

public function attempt($username, $password)
{
  $user = $this->userRepository->findByUsername($username);

  if (password_verify($password, $user->password)) { 
  if ($this->userRepository->isAdmin($user->username) == "admin") {
    $_SESSION['admin'] = "admin";
  }
  $_SESSION['login'] = $user->username;            
  session_regenerate_id(true);                    
  return true;                                      
}

This is a part of the __construct in the PostsAdminController.php in which I'm trying to get the value of the permission of the logged in user and save it into the session if it is "admin" and not "normal":

$username = $_SESSION['login'];
$permission = $this->userRepository->isAdmin($username);

if ($permission == "admin") {
  $_SESSION['admin'] = $permission;

I also have a part of the header, because for admins there is a different navigation as for normal user.

<?php if(!empty ($_SESSION['login'])):?>
  <div class="logged-in-user">
    <div class="dropdown">
      <button class="dropbtn">
        <a href="http://localhost:8888/blog/public/index.php/dashboard">
          <?php echo e($_SESSION['login']);?>
        </a>
      </button>
    <div class="dropdown-content">
      <?php if ($_SESSION['admin'] == "admin"): ?>
        <a href="http://localhost:8888/blog/public/index.php/dashboard">
          dashboard
        </a>

This won't give me the dashboard for both, the admin and the normal user. But if I ask if it's set:

<?php if (isset($_SESSION['admin'])): ?>

Then it shows the dashboard in the dropdown-navigation for both again...

I don't know why it doesn't work, so how do I correctly find out the permission of the logged in user and show them different things based on their permission?

ofmiceandmoon
  • 548
  • 2
  • 9
  • 30
  • `$stmt->fetch(PDO::FETCH_CLASS);` will return `array("permission" => "admin")` - so you should do `return $isAdmin['permission'];` (Or you can do `$stmt->fetchColumn();`) – GrumpyCrouton Dec 05 '18 at 13:53
  • Also, here it looks like you are passing the permission? `isAdmin($user->permission)`, shouldn't that be the username? – GrumpyCrouton Dec 05 '18 at 13:55
  • you're right, I corrected it. But it still doesn't work – ofmiceandmoon Dec 05 '18 at 13:59
  • You should update the code in your question with the corrections you did, so we know we are working from the same place, especially because there are no answers yet. – GrumpyCrouton Dec 05 '18 at 14:00
  • If you say "it still doesn't work" please can you show us your PHP error reports. (in your question, not in comments) – Martin Dec 05 '18 at 14:02
  • do you really have a function called `e`? How descriptive `:-p` – Martin Dec 05 '18 at 14:03
  • @Martin It's probably an output sanitizer of some kind – GrumpyCrouton Dec 05 '18 at 14:04
  • @Martin 1.) e stands for entities (htmlentities) 2.) I don't get an error, it just still shows the dashboard when both user are logged in – ofmiceandmoon Dec 05 '18 at 14:10
  • If the problem persists, use your IDE or use `print_r(...)` or `error_log(...)` to output data values at each step of the logic to see where the values are becoming unexpected. – Martin Dec 05 '18 at 14:54

1 Answers1

2

It looks easier simply for you to return a boolean for your function; rather than a string value,then you can use your function in comparisons with relative ease (see bottom of answer).

/***
 * Function for finding out if user is an admin
 * @param string $username 
 * @return bool isAdmin? 
 ***/
public function isAdmin($username)
{
  $table = $this->getTableName();
  $model = $this->getModelName();

  if(empty($username)){
     return false;
  }

  $stmt = $this->pdo->prepare("SELECT `permission` FROM `{$table}` WHERE username = :username");
  $stmt->execute(['username' => $username]);

  $stmt->setFetchMode(PDO::FETCH_CLASS, $model);
  $isAdminResult = $stmt->fetch(PDO::FETCH_CLASS); 

  if($isAdminResult['permission'] === "admin"){ 
      // YES this user is marked as an admin. 

      // You can also if you wish, save the admin details to a @_SESSION here
      // $_SESSION['admin'] == "admin";
      return true;
  }

  // No this user is not admin 
  return false;

} 

Then in your later code (in the PostsAdminController construct, for example):

if($this->userRepository->isAdmin($username)){
    // $_SESSION['admin'] = "Yeeeaahhh";
    // whatever you want to run for admins only. 
}

It's smoother and easier to compare the $_SESSION['admin'] value than to repeatedly run a database and class method call.

Martin
  • 22,212
  • 11
  • 70
  • 132
  • How can I put the if into the PostsAdminController? In the __Construct like I did before? The repository is only for the querys and nothing else, this is what the controllers are for – ofmiceandmoon Dec 05 '18 at 14:16
  • @ofmiceandmoon my `later code:...` block is taken from your question referencing the `PostsAdminController` construct . Therefore this code change should be obvious? – Martin Dec 05 '18 at 14:42
  • Ah I interpreted it as the codes I should put in the header when asking if the logged in user has the admin permission, my bad sorry – ofmiceandmoon Dec 05 '18 at 14:46
  • @ofmiceandmoon no worries - I have updated my answer. – Martin Dec 05 '18 at 14:48
  • And how can I achieve that `if ($isAdmin['permission'] === "admin" { ... " in the isAdmin()-function in the `userRepository` is in the `PostsAdminController`? I'm asking because I seperated the db interaction so that the querys have their own file (kinda) – ofmiceandmoon Dec 05 '18 at 14:55
  • and I did it just like you but it still doesn't work – ofmiceandmoon Dec 05 '18 at 14:58
  • I honestly don't know how to do that or where to put the error log. I am completely new in this world of programming – ofmiceandmoon Dec 05 '18 at 15:07
  • I var_dumped the $_SESSION['admin'] and logged in with both users, both were stated as admin – ofmiceandmoon Dec 05 '18 at 15:08
  • Then with the greatest respect, you need to learn to stand before you can try running. Please review [how to read PHP errors](https://stackoverflow.com/questions/1053424/how-do-i-get-php-errors-to-display) and many similar questions on Stack Overflow – Martin Dec 05 '18 at 15:09
  • Also you said above that you had no errors from your PHP error logs, and now you say you don't know how to read errors from the logs.... We can't help you without your help. – Martin Dec 05 '18 at 15:09
  • the thing is, aren't the error messages get written in a file? I didn't install the ide, for e.g. the htdocs folder is empty – ofmiceandmoon Dec 05 '18 at 15:12
  • When you log out a user or when you log in again you should clear your users session data by doing . `$_SESSION = [];` Because even if a user logs out the session data remains the same unless set otherwise. – Martin Dec 05 '18 at 15:12
  • PHP error messages are written to a file as defined in the `php.ini` core. On a new page set: [`phpinfo();`](http://php.net/manual/en/function.phpinfo.php) and read the (large) output and find `error_log` to see where on your system PHP is putting the error logs. Good luck. – Martin Dec 05 '18 at 15:13
  • 1
    Thank you, and sorry for probably make you cry because I don't know much :D $_SESSION[] solved the Problem. – ofmiceandmoon Dec 05 '18 at 15:17
  • @ofmiceandmoon hahaha, no worries at all. Glad to get the problem fixed. Crying is all part of the game `;-)` – Martin Dec 05 '18 at 15:38