You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2017/03/23 18:37:51 UTC
airavata-php-gateway git commit: AIRAVATA-2342 WIP implementation on
user roles management
Repository: airavata-php-gateway
Updated Branches:
refs/heads/keycloak-integration c92cc2b9b -> 471b3808b
AIRAVATA-2342 WIP implementation on user roles management
Project: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/commit/471b3808
Tree: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/tree/471b3808
Diff: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/diff/471b3808
Branch: refs/heads/keycloak-integration
Commit: 471b3808b85ebd6dac6b31b025b90f92fcf64f34
Parents: c92cc2b
Author: Marcus Christie <ma...@iu.edu>
Authored: Thu Mar 23 14:36:40 2017 -0400
Committer: Marcus Christie <ma...@iu.edu>
Committed: Thu Mar 23 14:36:40 2017 -0400
----------------------------------------------------------------------
app/controllers/AdminController.php | 34 +++++-----
app/libraries/Keycloak/API/RoleMapper.php | 40 ++++++++++-
app/libraries/Keycloak/API/Roles.php | 78 ++++++++++++++++++++++
app/libraries/Keycloak/API/Users.php | 85 ++++++++++++++++++++++++
app/libraries/Keycloak/Keycloak.php | 91 ++++++++++++++++++++++++++
app/views/admin/manage-users.blade.php | 24 ++++---
6 files changed, 324 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/471b3808/app/controllers/AdminController.php
----------------------------------------------------------------------
diff --git a/app/controllers/AdminController.php b/app/controllers/AdminController.php
index 6dd27bd..b2f95d7 100644
--- a/app/controllers/AdminController.php
+++ b/app/controllers/AdminController.php
@@ -70,9 +70,9 @@ class AdminController extends BaseController {
$users = AdminController::getUsersWithRole( Input::get("role"));
}
else
- $users = WSIS::listUsers();
+ $users = Keycloak::listUsers();
- $roles = WSIS::getAllRoles();
+ $roles = Keycloak::getAllRoles();
Session::put("admin-nav", "manage-users");
return View::make("admin/manage-users", array("users" => $users, "roles" => $roles));
}
@@ -88,12 +88,12 @@ class AdminController extends BaseController {
$users = WSIS::searchUsers(Input::get("search_val"));
}
else
- $users = WSIS::listUsers();
+ $users = Keycloak::listUsers();
if(!isset($users) || empty($users)){
$users = array();
}
- $roles = WSIS::getAllRoles();
+ $roles = Keycloak::getAllRoles();
Session::put("admin-nav", "manage-users");
return View::make("admin/manage-users", array("users" => $users, "roles" => $roles));
@@ -184,7 +184,7 @@ class AdminController extends BaseController {
}
public function rolesView(){
- $roles = WSIS::getAllRoles();
+ $roles = Keycloak::getAllRoles();
Session::put("admin-nav", "manage-roles");
return View::make("admin/manage-roles", array("roles" => $roles));
}
@@ -211,7 +211,7 @@ class AdminController extends BaseController {
}
public function addRolesToUser(){
- $currentRoles = WSIS::getUserRoles(Input::get("username"));
+ $currentRoles = Keycloak::getUserRoles(Input::get("userId"));
if(!is_array($currentRoles))
$currentRoles = array($currentRoles);
$roles["new"] = array_diff(Input::all()["roles"], $currentRoles);
@@ -227,12 +227,12 @@ class AdminController extends BaseController {
unset($roles["deleted"][$index]);
}
- $username = Input::all()["username"];
- WSIS::updateUserRoles($username, $roles);
- $newCurrentRoles = WSIS::getUserRoles(Input::get("username"));
+ $userId = Input::all()["userId"];
+ Keycloak::updateUserRoles($userId, $roles);
+ $newCurrentRoles = Keycloak::getUserRoles($userId);
if(in_array(Config::get("pga_config.wsis")["admin-role-name"], $newCurrentRoles) || in_array(Config::get("pga_config.wsis")["read-only-admin-role-name"], $newCurrentRoles)
|| in_array(Config::get("pga_config.wsis")["user-role-name"], $newCurrentRoles)){
- $userProfile = WSIS::getUserProfile(Input::get("username"));
+ $userProfile = Keycloak::getUserProfile($userId);
$recipients = array($userProfile["email"]);
$this->sendAccessGrantedEmailToTheUser(Input::get("username"), $recipients);
@@ -246,12 +246,12 @@ class AdminController extends BaseController {
if(in_array($initialRoleName, $newCurrentRoles) && !in_array($initialRoleName, $roles["new"])) {
$userRoles["new"] = array();
$userRoles["deleted"] = $initialRoleName;
- WSIS::updateUserRoles( $username, $userRoles);
+ Keycloak::updateUserRoles( $userId, $userRoles);
} else if(in_array($initialRoleName, $newCurrentRoles) && in_array($initialRoleName, $roles["new"])) {
// When initial role added remove all roles except for initial role and Internal/everyone
$userRoles["new"] = array();
$userRoles["deleted"] = array_diff($newCurrentRoles, array($initialRoleName, "Internal/everyone"));
- WSIS::updateUserRoles( $username, $userRoles);
+ Keycloak::updateUserRoles( $userId, $userRoles);
}
}
}
@@ -277,13 +277,13 @@ class AdminController extends BaseController {
public function removeRoleFromUser(){
$roles["deleted"] = array(Input::all()["roleName"]);
$roles["new"] = array();
- $username = Input::all()["username"];
- WSIS::updateUserRoles($username, $roles);
+ $userId = Input::all()["userId"];
+ Keycloak::updateUserRoles($userId, $roles);
return Redirect::to("admin/dashboard/roles")->with( "message", "Role has been deleted.");
}
public function getRoles(){
- return json_encode((array)WSIS::getUserRoles(Input::get("username")));
+ return json_encode((array)Keycloak::getUserRoles(Input::get("userId")));
}
public function deleteRole(){
@@ -300,7 +300,7 @@ class AdminController extends BaseController {
return View::make("admin/manage-credentials", array("tokens" => $tokens , "pwdTokens" => $pwdTokens) );
}
- private function sendAccessGrantedEmailToTheUser($username, $recipients){
+ private function sendAccessGrantedEmailToTheUser($username, $userId, $recipients){
$mail = new PHPMailer;
@@ -326,7 +326,7 @@ class AdminController extends BaseController {
$mail->isHTML(true);
$mail->Subject = "Your user account (".$username.") privileges changed!";
- $userProfile = WSIS::getUserProfile($username);
+ $userProfile = WSIS::getUserProfile($userId);
$wsisConfig = Config::get('pga_config.wsis');
if( $wsisConfig['tenant-domain'] == "")
$username = $username;
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/471b3808/app/libraries/Keycloak/API/RoleMapper.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/RoleMapper.php b/app/libraries/Keycloak/API/RoleMapper.php
index 2e6d170..e79246e 100644
--- a/app/libraries/Keycloak/API/RoleMapper.php
+++ b/app/libraries/Keycloak/API/RoleMapper.php
@@ -35,7 +35,9 @@ class RoleMapper {
// get access token for admin API
$access_token = $this->getAPIAccessToken();
- $r = curl_init($this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id) . '/role-mappings/realm');
+ $url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id) . '/role-mappings/realm';
+ // Log::debug("getRealmRoleMappingsForUser url", array($url));
+ $r = curl_init($url);
curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($r, CURLOPT_ENCODING, 1);
curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
@@ -45,6 +47,7 @@ class RoleMapper {
$response = curl_exec($r);
if ($response == false) {
+ Log::error("Failed to retrieve realm role mappings for user");
die("curl_exec() failed. Error: " . curl_error($r));
}
$result = json_decode($response);
@@ -52,6 +55,40 @@ class RoleMapper {
return $result;
}
+ // TODO: change this to an Array of role representations
+ public function addRealmRoleMappingsToUser($realm, $user_id, $role_representations) {
+
+ // get access token for admin API
+ $access_token = $this->getAPIAccessToken();
+ $url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id) . '/role-mappings/realm';
+ // Log::debug("addRealmRoleMappingsToUser", array($url, $role_representations));
+ $r = curl_init($url);
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+ curl_setopt($r, CURLOPT_HTTPHEADER, array(
+ "Authorization: Bearer " . $access_token
+ ));
+
+ curl_setopt($r, CURLOPT_POST, true);
+ $data = json_encode($role_representations);
+ curl_setopt($r, CURLOPT_HTTPHEADER, array(
+ 'Content-Type: application/json',
+ 'Content-Length: ' . strlen($data))
+ );
+ curl_setopt($r, CURLOPT_POSTFIELDS, $data);
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ Log::error("Failed to add realm role mapping to user");
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+ $result = json_decode($response);
+ $info = curl_getinfo($r);
+ // Log::debug("addRealmRoleMappingsToUser result", array($result, $info));
+ return $result;
+ }
+
// TODO: factor this out into base class?
private function getAPIAccessToken() {
@@ -73,6 +110,7 @@ class RoleMapper {
$response = curl_exec($r);
if ($response == false) {
+ Log::error("Failed to retrieve API Access Token");
die("curl_exec() failed. Error: " . curl_error($r));
}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/471b3808/app/libraries/Keycloak/API/Roles.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/Roles.php b/app/libraries/Keycloak/API/Roles.php
new file mode 100644
index 0000000..02f5b8f
--- /dev/null
+++ b/app/libraries/Keycloak/API/Roles.php
@@ -0,0 +1,78 @@
+<?php
+namespace Keycloak\API;
+
+/**
+ * Roles class
+ *
+ * This class provide an easy to use interface for
+ * the Keycloak Roles REST API.
+ */
+class Roles {
+
+ private $base_endpoint_url;
+ private $admin_username;
+ private $admin_password;
+ private $verify_peer;
+
+ public function __construct($base_endpoint_url, $admin_username, $admin_password, $verify_peer) {
+ $this->base_endpoint_url = $base_endpoint_url;
+ $this->admin_username = $admin_username;
+ $this->admin_password = $admin_password;
+ $this->verify_peer = $verify_peer;
+ }
+
+ /**
+ * Get representations of all of a realm's roles
+ * GET /admin/realms/{realm}/roles
+ * Returns Array of RoleRepresentation
+ */
+ public function getRoles($realm){
+
+ // get access token for admin API
+ $access_token = $this->getAPIAccessToken();
+ $r = curl_init($this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/roles');
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+ curl_setopt($r, CURLOPT_HTTPHEADER, array(
+ "Authorization: Bearer " . $access_token
+ ));
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+ $result = json_decode($response);
+ // Log::debug("getRealmRoleMappingsForUser result", array($result));
+ return $result;
+ }
+
+ // TODO: factor this out into base class?
+ private function getAPIAccessToken() {
+
+ // http://www.keycloak.org/docs/2.5/server_development/topics/admin-rest-api.html
+ // curl -d client_id=admin-cli -d username=username \
+ // -d "password=password" -d grant_type=password https://149.165.156.62:8443/auth/realms/master/protocol/openid-connect/token
+
+ $r = curl_init($this->base_endpoint_url . '/realms/master/protocol/openid-connect/token');
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+
+ // Assemble POST parameters for the request.
+ $post_fields = "client_id=admin-cli&username=" . urlencode($this->admin_username) . "&password=" . urlencode($this->admin_password) . "&grant_type=password";
+
+ // Obtain and return the access token from the response.
+ curl_setopt($r, CURLOPT_POST, true);
+ curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+
+ $result = json_decode($response);
+ // Log::debug("API Access Token result", array($result));
+ return $result->access_token;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/471b3808/app/libraries/Keycloak/API/Users.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/Users.php b/app/libraries/Keycloak/API/Users.php
new file mode 100644
index 0000000..ac99995
--- /dev/null
+++ b/app/libraries/Keycloak/API/Users.php
@@ -0,0 +1,85 @@
+<?php
+namespace Keycloak\API;
+
+use Log;
+
+/**
+ * Users class
+ *
+ * This class provide an easy to use interface for
+ * the Keycloak Users REST API.
+ */
+class Users {
+
+ private $base_endpoint_url;
+ private $admin_username;
+ private $admin_password;
+ private $verify_peer;
+
+ public function __construct($base_endpoint_url, $admin_username, $admin_password, $verify_peer) {
+ $this->base_endpoint_url = $base_endpoint_url;
+ $this->admin_username = $admin_username;
+ $this->admin_password = $admin_password;
+ $this->verify_peer = $verify_peer;
+ }
+
+ /**
+ * Get representations of all users
+ * GET /admin/realms/{realm}/users
+ * Returns Array of UserRepresentation
+ */
+ public function getUsers($realm, $username = null){
+
+ // get access token for admin API
+ $access_token = $this->getAPIAccessToken();
+ $url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users';
+ if ($username) {
+ $url = $url . '?username=' . rawurlencode($username);
+ }
+ // Log::debug("getUsers url", array($url));
+ $r = curl_init($this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users');
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+ curl_setopt($r, CURLOPT_HTTPHEADER, array(
+ "Authorization: Bearer " . $access_token
+ ));
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+ $result = json_decode($response);
+ // Log::debug("getUsers result", array($result));
+ return $result;
+ }
+
+ // TODO: factor this out into base class?
+ private function getAPIAccessToken() {
+
+ // http://www.keycloak.org/docs/2.5/server_development/topics/admin-rest-api.html
+ // curl -d client_id=admin-cli -d username=username \
+ // -d "password=password" -d grant_type=password https://149.165.156.62:8443/auth/realms/master/protocol/openid-connect/token
+
+ $r = curl_init($this->base_endpoint_url . '/realms/master/protocol/openid-connect/token');
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+
+ // Assemble POST parameters for the request.
+ $post_fields = "client_id=admin-cli&username=" . urlencode($this->admin_username) . "&password=" . urlencode($this->admin_password) . "&grant_type=password";
+
+ // Obtain and return the access token from the response.
+ curl_setopt($r, CURLOPT_POST, true);
+ curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+
+ $result = json_decode($response);
+ // Log::debug("API Access Token result", array($result));
+ return $result->access_token;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/471b3808/app/libraries/Keycloak/Keycloak.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/Keycloak.php b/app/libraries/Keycloak/Keycloak.php
index 93ac99d..5dc57d4 100644
--- a/app/libraries/Keycloak/Keycloak.php
+++ b/app/libraries/Keycloak/Keycloak.php
@@ -3,7 +3,10 @@
namespace Keycloak;
use Keycloak\API\RoleMapper;
+use Keycloak\API\Roles;
+use Keycloak\API\Users;
+use Exception;
use Log;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\Facades\Config;
@@ -17,7 +20,10 @@ class Keycloak {
private $callback_url;
private $verify_peer;
+ // API clients
private $role_mapper;
+ private $roles;
+ private $users;
/**
* Constructor
@@ -33,6 +39,8 @@ class Keycloak {
$this->verify_peer = $verify_peer;
$this->role_mapper = new RoleMapper($base_endpoint_url, $admin_username, $admin_password, $verify_peer);
+ $this->roles = new Roles($base_endpoint_url, $admin_username, $admin_password, $verify_peer);
+ $this->users = new Users($base_endpoint_url, $admin_username, $admin_password, $verify_peer);
}
public function getOAuthRequestCodeUrl(){
@@ -118,6 +126,89 @@ class Keycloak {
return array('username'=>$username, 'firstname'=>$firstname, 'lastname'=>$lastname, 'email'=>$email, 'roles'=>$roles);
}
+ /**
+ * Function to list users
+ *
+ * @return Array of username and user id
+ */
+ public function listUsers(){
+ $users = $this->users->getUsers($this->realm);
+ $user_infos = [];
+ foreach ($users as $user) {
+ $user_infos[] = array("username" => $user->username, "id" => $user->id);
+ }
+ return $user_infos;
+ }
+
+ /**
+ * Function to get the list of all existing roles
+ * For Keycloak this is a list of "Realm roles"
+ *
+ * @return roles list
+ */
+ public function getAllRoles(){
+ try {
+ $roles = $this->roles->getRoles($this->realm);
+ $role_names = [];
+ foreach ($roles as $role) {
+ $role_names[] = $role->name;
+ }
+ return $role_names;
+ } catch (Exception $ex) {
+ throw new Exception("Unable to get all roles", 0, $ex);
+ }
+ }
+
+ /**
+ * Function to get roles of a user
+ * For Keycloak this is a list of "Realm roles"
+ *
+ * @return array of role names
+ */
+ public function getUserRoles( $userid ){
+ try {
+ // Get the user's realm roles, then convert to an array of just names
+ $roles = $this->role_mapper->getRealmRoleMappingsForUser($this->realm, $userid);
+ $role_names = [];
+ foreach ($roles as $role) {
+ $role_names[] = $role->name;
+ }
+ return $role_names;
+ } catch (Exception $ex) {
+ throw new Exception("Unable to get User roles.", 0, $ex);
+ }
+ }
+
+ /**
+ * Function to update role list of user
+ *
+ * @param $user_id
+ * @param $roles, an Array with two entries, "deleted" and "new", each of
+ * which has a value of roles to be removed or added respectively
+ * @return void
+ */
+ public function updateUserRoles( $user_id, $roles){
+ Log::debug("updateUserRoles", array($user_id, $roles));
+ try {
+ // Get all of the roles into an array keyed by role name
+ $all_roles = $this->roles->getRoles($this->realm);
+ $roles_by_name = [];
+ foreach ($all_roles as $role) {
+ $roles_by_name[$role->name] = $role;
+ }
+ // Process the role additions
+ if(isset($roles["new"])){
+ if(!is_array($roles["new"]))
+ $roles["new"] = array($roles["new"]);
+ foreach ($roles["new"] as $role) {
+ $this->role_mapper->addRealmRoleMappingsToUser($this->realm, $user_id, array($roles_by_name[$role]));
+ }
+ }
+ } catch (Exception $ex) {
+ throw new Exception("Unable to update role of the user.", 0, $ex);
+ }
+ }
+
private function getOpenIDConnectDiscoveryConfiguration() {
// TODO: cache the result of the request
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/471b3808/app/views/admin/manage-users.blade.php
----------------------------------------------------------------------
diff --git a/app/views/admin/manage-users.blade.php b/app/views/admin/manage-users.blade.php
index 9f36ca8..15818ae 100644
--- a/app/views/admin/manage-users.blade.php
+++ b/app/views/admin/manage-users.blade.php
@@ -68,10 +68,10 @@
</tr>
@foreach( (array)$users as $user)
<tr class="user-row">
- <td>{{ $user }}</td>
+ <td>{{ $user["username"] }}</td>
<td>
<button class="button btn btn-default check-roles" type="button"
- data-username="{{$user}}">Check All Roles
+ data-username="{{$user["username"]}}" data-userid="{{$user["id"]}}">Check All Roles
</button>
<div class="user-roles"></div>
</td>
@@ -113,7 +113,7 @@
@endif
@endforeach
</select>
- <button type="button" class="btn btn-primary add-roles-submit" data-username="">Add Roles
+ <button type="button" class="btn btn-primary add-roles-submit" data-username="" data-userid="">Add Roles
</button>
</div>
</div>
@@ -161,12 +161,12 @@
type: "POST",
url: $(".base-url").val() + "/admin/remove-role-from-user",
data: {
- username: userName,
+ userId: userId,
roleName:$(this).attr("roleName")
}
}).complete(function (data) {
//getting user's existing roles
- repopulatePopup( userName);
+ repopulatePopup( userName, userId );
$(".success-message").html("<span class='alert alert-success col-md-12'>Role has been removed</span>");
});
}
@@ -174,7 +174,8 @@
function update_users_existing_roles(that){
userName = $(that).data("username");
- repopulatePopup( userName);
+ userId = $(that).data("userid");
+ repopulatePopup( userName, userId );
}
$(".check-roles").click(function () {
@@ -191,7 +192,8 @@
$(".success-message").html("");
$(this).attr("disabled", "disabled");
$(this).html("<img src='" + $(".base-url").val() + "/assets/ajax-loader.gif'/>");
- userName = $(this).data("username");
+ userId = $(this).data("userid");
+ username = $(this).data("username");
var rolesToAdd = $(".new-roles-select").val();
if(rolesToAdd != null){
$(".roles-list").find(".role-name").each(function () {
@@ -202,7 +204,8 @@
url: $(".base-url").val() + "/admin/add-roles-to-user",
data: {
add: true,
- username: userName,
+ userId: userId,
+ username: username,
roles: rolesToAdd
},
success : function(data)
@@ -221,20 +224,21 @@
}
});
- function repopulatePopup( username){
+ function repopulatePopup( userName, userId ){
$("#check-role-block").modal("show");
$(".roles-of-user").html("User : " + userName);
$(".roles-load").removeClass("hide");
$(".roles-list").addClass("hide");
$(".add-roles-submit").data("username", userName);
+ $(".add-roles-submit").data("userid", userId);
$(document).find(".alert-success").remove();
$.ajax({
type: "POST",
url: $(".base-url").val() + "/admin/check-roles",
data: {
- username: userName
+ userId: userId
}
}).complete(function (data) {
roles = JSON.parse(data.responseText);