Skip to content

Commit

Permalink
Merge pull request #150 from thanujalk/master
Browse files Browse the repository at this point in the history
Add new conditional functions based on Role V2
  • Loading branch information
thanujalk authored Dec 15, 2023
2 parents 6e70018 + 36471df commit 3373409
Show file tree
Hide file tree
Showing 9 changed files with 524 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,16 @@
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.application.authentication.framework.dao;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.application.mgt;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.base.*; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.core.util.*; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.core.model.*; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.user.profile.mgt; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.user.profile.mgt.dao; version="${carbon.identity.package.import.version.range}",
org.apache.commons.collections,
org.wso2.carbon.identity.role.v2.mgt.core.*;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.user.api; version="${carbon.user.package.import.version.range}",
org.wso2.carbon.user.core; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.user.core.util; version="${carbon.kernel.package.import.version.range}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.conditional.auth.functions.user;

import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext;

import java.util.List;

/**
* Function to update given roles(v2) for a given user.
* The purpose is to perform role(v2) assigning during dynamic authentication.
*/
@FunctionalInterface
public interface AssignUserRolesV2Function {

/**
* Add roles for a given <code>user</code>
*
* @param context authentication context
* @param roleListToAssign Roles to be assigned.
* @return <code>true</code> If the role assigning is successfully completed. <code>false</code> for any other case.
*/
boolean assignUserRolesV2(JsAuthenticationContext context, List<String> roleListToAssign);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.conditional.auth.functions.user;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext;
import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.AssociatedRolesConfig;
import org.wso2.carbon.identity.application.common.model.RoleV2;
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
import org.wso2.carbon.identity.conditional.auth.functions.user.internal.UserFunctionsServiceHolder;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
* Implementation of the function to assign given roles for a given user.
*/
public class AssignUserRolesV2FunctionImpl implements AssignUserRolesV2Function {

private static final Log LOG = LogFactory.getLog(AssignUserRolesV2FunctionImpl.class);

@Override
public boolean assignUserRolesV2(JsAuthenticationContext context, List<String> roleListToAssign) {

if (roleListToAssign == null || roleListToAssign.isEmpty()) {
return false;
}

AuthenticatedUser subject = context.getWrapped().getSubject();
if (subject.isFederatedUser()) {
return false;
}

String applicationName = context.getWrapped().getServiceProviderName();
String tenantDomain = context.getWrapped().getTenantDomain();

ServiceProvider application;
try {
application = UserFunctionsServiceHolder.getInstance().getApplicationManagementService()
.getApplicationExcludingFileBasedSPs(applicationName, tenantDomain);
} catch (IdentityApplicationManagementException e) {
LOG.error("Error occurred while retrieving the application", e);
return false;
}

AssociatedRolesConfig associatedRolesConfig = application.getAssociatedRolesConfig();
if (associatedRolesConfig == null || associatedRolesConfig.getRoles() == null
|| associatedRolesConfig.getRoles().length == 0) {
// No roles associated with the application.
return false;
}

List<RoleV2> associatedRoles = Arrays.asList(associatedRolesConfig.getRoles());
List<RoleV2> allowedRoleListToAssign = new ArrayList<>();
for (String roleName : roleListToAssign) {
// Check if the provided role name is associated with the application.
Optional<RoleV2> roleOptional =
associatedRoles.stream().filter(role -> role.getName().equals(roleName)).findFirst();
roleOptional.ifPresent(allowedRoleListToAssign::add);
}

if (allowedRoleListToAssign.isEmpty()) {
return false;
}

for (RoleV2 role : allowedRoleListToAssign) {
try {
UserFunctionsServiceHolder.getInstance().getRoleManagementService()
.updateUserListOfRole(role.getId(), Collections.singletonList(subject.getUserId()),
Collections.emptyList(), tenantDomain);
} catch (IdentityRoleManagementException | UserIdNotFoundException e) {
LOG.error("Error occurred while updating the roles of the user", e);
return false;
}
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.conditional.auth.functions.user;

import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext;

import java.util.List;

/**
* Function to check if the given user has at least one of the given roles(v2).
* The purpose is to perform dynamic authentication selection based on user role(v2).
*/
@FunctionalInterface
public interface HasAnyOfTheRolesV2Function {

/**
* Check if the user in the authentication context has any of the given roles.
*
* @param context authentication context
* @param roleNames Role to be checked
* @return <code>true</code> if the user has at least one of the given roles. <code>false</code> for any other
* case.
*/
boolean hasAnyOfTheRolesV2(JsAuthenticationContext context, List<String> roleNames);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.conditional.auth.functions.user;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext;
import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException;
import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.AssociatedRolesConfig;
import org.wso2.carbon.identity.application.common.model.RoleV2;
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
import org.wso2.carbon.identity.conditional.auth.functions.user.internal.UserFunctionsServiceHolder;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
* Implementation of the function to check if the given user has at least one of the given roles(v2).
*/
public class HasAnyOfTheRolesV2FunctionImpl implements HasAnyOfTheRolesV2Function {

private static final Log LOG = LogFactory.getLog(HasAnyOfTheRolesV2FunctionImpl.class);

@Override
public boolean hasAnyOfTheRolesV2(JsAuthenticationContext context, List<String> roleNames) {

if (roleNames == null || roleNames.isEmpty()) {
return false;
}

AuthenticatedUser subject = context.getWrapped().getSubject();
if (subject.isFederatedUser()) {
return false;
}

String applicationName = context.getWrapped().getServiceProviderName();
String tenantDomain = context.getWrapped().getTenantDomain();

ServiceProvider application;
try {
application = UserFunctionsServiceHolder.getInstance().getApplicationManagementService()
.getApplicationExcludingFileBasedSPs(applicationName, tenantDomain);
} catch (IdentityApplicationManagementException e) {
LOG.error("Error occurred while retrieving the application", e);
return false;
}

AssociatedRolesConfig associatedRolesConfig = application.getAssociatedRolesConfig();
if (associatedRolesConfig == null || associatedRolesConfig.getRoles() == null
|| associatedRolesConfig.getRoles().length == 0) {
// No roles associated with the application.
return false;
}

List<RoleBasicInfo> roleListOfUser;
try {
roleListOfUser = UserFunctionsServiceHolder.getInstance().getRoleManagementService()
.getRoleListOfUser(subject.getUserId(), tenantDomain);
} catch (IdentityRoleManagementException | UserIdNotFoundException e) {
LOG.error("Error occurred while retrieving the user", e);
return false;
}

if (roleListOfUser == null || roleListOfUser.isEmpty()) {
return false;
}

List<RoleV2> associatedRoles = Arrays.asList(associatedRolesConfig.getRoles());
for (String roleName : roleNames) {
// Check if the provided role name is associated with the application.
Optional<RoleV2> roleOptional =
associatedRoles.stream().filter(role -> role.getName().equals(roleName)).findFirst();

if (roleOptional.isPresent()) {
// Check if the user has the role from role id.
Optional<RoleBasicInfo> role2 = roleListOfUser.stream()
.filter(roleBasicInfo -> roleBasicInfo.getId().equals(roleOptional.get().getId()))
.findFirst();
if (role2.isPresent()) {
return true;
}
}
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.conditional.auth.functions.user;

import org.wso2.carbon.identity.application.authentication.framework.config.model.graph.js.JsAuthenticationContext;

import java.util.List;

/**
* Function to remove given roles(v2) for a given user.
* The purpose is to perform role(v2) removing during dynamic authentication.
*/
@FunctionalInterface
public interface RemoveUserRolesV2Function {

/**
* Remove roles for a given <code>user</code>
*
* @param context authentication context
* @param roleListToRemove Roles to be removed.
* @return <code>true</code> If the role removal is successfully completed. <code>false</code> for any other case.
*/
boolean removeUserRolesV2(JsAuthenticationContext context, List<String> roleListToRemove);
}
Loading

0 comments on commit 3373409

Please sign in to comment.