Skip to content

Commit

Permalink
fix web auth and guard for ci3 framework by load session library from…
Browse files Browse the repository at this point in the history
… CodeIgniter 3 in order to save state, validate state, and retrieve token
  • Loading branch information
kresnasatya committed Jun 27, 2024
1 parent 8a2bb29 commit fe90c19
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 76 deletions.
81 changes: 47 additions & 34 deletions stubs/ci3/controllers/Webauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
use RistekUSDI\SSO\PHP\Exceptions\CallbackException;
use RistekUSDI\SSO\PHP\Services\SSOService;
use RistekUSDI\SSO\PHP\Auth\Guard\WebGuard;
use RistekUSDI\SSO\PHP\Auth\AccessToken;

class Webauth extends CI_Controller {

public function __construct()
{
parent::__construct();
$this->CI =& get_instance();
$this->load->helper('url');
$this->load->library('session');
}

public function login()
Expand Down Expand Up @@ -60,7 +59,7 @@ public function callback()
// You may need to create a custom session for your internal app
$this->createSession();

redirect('/home');
redirect('home', 'location', 301);
} catch (\Exception $e) {
throw new CallbackException($e->getCode(), $e->getMessage());
}
Expand All @@ -82,51 +81,65 @@ public function impersonate()

$this->createSession();

redirect('/home');
redirect('home', 'location', 301);
} catch (\Throwable $th) {
echo "Status code: {$th->getCode()} \n";
echo "Error message: {$th->getMessage()}\n";
die();
}
}

/**
* You may be create a session to get roles and permission that belongs to each role.
* After user logged in, they may have list of roles based on a client (app) that stored in client_roles property.
* Use "client_roles" property as parameter to get roles and permissions in your app database.
* Expected result is a serialize of array that store in a session called serialize session.
* The array contains:
* - roles (list of roles with permissions belongs to each role)
* - role (active or current role)
*/
private function createSession()
{
$client_roles = (new WebGuard)->user()->client_roles;

$roles = $this->db->query("SELECT role_id AS id, role_name as `name` FROM rbac_roles
WHERE rbac_roles.role_name IN ?", array($client_roles))->result();

foreach ($roles as $key => $role) {
$role_permissions = $this->db->query("SELECT rbac_permissions.perm_desc
FROM rbac_permissions
INNER JOIN rbac_role_perm ON rbac_role_perm.perm_id = rbac_permissions.perm_id
WHERE rbac_role_perm.`role_id` = ?", array($role->id))->result_array();

$roles[$key]->permissions = array_column($role_permissions, 'perm_desc');
}

// NOTE: You maybe want to get roles from your database by using $client_roles
// and put permissions to each role.
// Here's is example of result.
$roles = json_decode(json_encode([
[
'id' => 1,
'name' => 'Operator',
'permissions' => [
'user:view',
'user:edit',
]
],
[
'id' => 2,
'name' => 'User',
'permissions' => [
'profile:view',
'profile:edit',
]
],
]));
// Here's is the expected result.
// $roles = json_decode(json_encode([
// [
// 'id' => 1,
// 'name' => 'Operator',
// 'permissions' => [
// 'user:view',
// 'user:edit',
// ]
// ],
// [
// 'id' => 2,
// 'name' => 'User',
// 'permissions' => [
// 'profile:view',
// 'profile:edit',
// ]
// ],
// ]));

$serialize_session = serialize(array(
$_SESSION['serialize_session'] = serialize(array(
'roles' => $roles,
'role' => $roles[0],
));

// PHP_SESSION_NONE if sessions are enabled, but none exists.
// https://www.php.net/manual/en/function.session-status.php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}

$_SESSION['serialize_session'] = $serialize_session;
'role' => $roles[0], // This is a active or current role
));
}

/**
Expand Down
60 changes: 18 additions & 42 deletions stubs/ci3/libraries/Webguard.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<?php

use RistekUSDI\SSO\PHP\Exceptions\CallbackException;
use RistekUSDI\SSO\PHP\Services\SSOService;
use RistekUSDI\SSO\PHP\Auth\Guard\WebGuard as Guard;
use RistekUSDI\SSO\PHP\Auth\AccessToken;

class Webguard {

private $user;
private $ci;

public function __construct()
{
$ci =& get_instance();
$this->ci = $ci;
$this->ci->load->library('session');
$this->user = (new Guard)->user();
}

Expand All @@ -26,7 +28,13 @@ public function authenticated()

public function check()
{
return (new Guard())->check();
$credentials = (new SSOService())->retrieveToken();
if ($credentials) {
$user = (new SSOService)->getUserProfile($credentials);
return $user ? true : false;
} else {
return false;
}
}

public function guest()
Expand All @@ -48,55 +56,23 @@ public function get()
return $this->user;
}

/**
* Check if user has specific role
* @return boolean
*/
public function hasRole($role)
public function hasRole($roles)
{
$result = false;
$roles_attr = $this->user->roles;
$role_names = array_column($roles_attr, 'name');
if (is_array($role)) {
$roles = $role;
$result = !empty(array_intersect($role_names , (array) $roles));
} else {
$result = in_array($role, $role_names) ? true : false;
}

$result = empty(array_diff((array) $roles, $this->user()->get()->roles));
$this->user->hasRole = $result;
return $this->user->hasRole;
}

/**
* Check if user has permission(s) from specific role
* @return boolean
*/
public function hasPermission($permission)
public function hasPermission($permissions)
{
$result = false;
$role_permissions = [];
if (isset($this->user->role->permissions)) {
foreach ($this->user->role->permissions as $perm) {
array_push($role_permissions, $perm);
}
}

if (is_array($permission)) {
$permissions = $permission;

$result = !empty(array_intersect((array) $role_permissions, (array) $permissions));
} else {
$result = in_array($permission, $role_permissions) ? true : false;
}

$result = !empty(array_intersect((array) $permissions, $this->user->role->permissions));
$this->user->hasPermission = $result;
return $this->user->hasPermission;
}

public function restrictAjax()
public function restrictAjaxLogin()
{
if (!$this->is_logged_in()) {
if (!$this->check()) {
$response['submit'] = 403;
$response['error'] = 'Your session has been expired, please login again';
header('Content-Type: application/json; charset=utf-8');
Expand Down

0 comments on commit fe90c19

Please sign in to comment.