Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional View Access For Discoverable Applications in MyAccount #6283

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6db9468
add discoverable groups attribute into service provider model
DilshanSenarath Jan 14, 2025
f980f54
add a new table to keep the app group association
DilshanSenarath Jan 14, 2025
18ae74d
implement functionality to retrieve and update discoverable groups
DilshanSenarath Jan 20, 2025
3a3cc93
remove unnecessary imports
DilshanSenarath Jan 20, 2025
a771053
implement groups meta service for applications
DilshanSenarath Jan 21, 2025
0907294
Merge branch 'master' into discoverable-apps
DilshanSenarath Jan 22, 2025
a575499
Merge branch 'wso2:master' into discoverable-apps
DilshanSenarath Jan 22, 2025
0846448
remove redundant discoverable groups resolving logic
DilshanSenarath Jan 22, 2025
ba14222
remove domain name validation
DilshanSenarath Jan 22, 2025
2fe16bf
add domain name validation
DilshanSenarath Jan 25, 2025
9b66cae
fix the domain name fallback issue
DilshanSenarath Jan 25, 2025
8759bc0
remove domain qualified group id creation
DilshanSenarath Jan 26, 2025
5478ee8
remove unused import
DilshanSenarath Jan 26, 2025
a0fc4c3
update runtime resolving logic for discoverable apps
DilshanSenarath Jan 26, 2025
ac6aa39
update runtime resolving logic for discoverable apps in filtering ser…
DilshanSenarath Jan 27, 2025
4d308de
add unit tests for getGroups service method
DilshanSenarath Jan 28, 2025
f26f274
add unit tests for util method
DilshanSenarath Jan 28, 2025
e5aaf8d
add unit tests for application dao
DilshanSenarath Jan 29, 2025
a1bf69d
add unit tests for application validator
DilshanSenarath Jan 29, 2025
d55266d
Merge branch 'master' into discoverable-apps
DilshanSenarath Jan 29, 2025
7580ecb
close the mocked static classes
DilshanSenarath Jan 29, 2025
8dabebf
update copyright headers
DilshanSenarath Jan 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2025, 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.application.common.model;

import org.apache.axiom.om.OMElement;
import org.apache.commons.lang.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

/**
* The list of groups through which the application can be discovered in my account.
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "DiscoverableGroup")
public class DiscoverableGroup implements Serializable {

private static final long serialVersionUID = -3030000000000000000L;
private static final String USER_STORE = "UserStore";
private static final String GROUPS = "Groups";
private static final String GROUP = "Group";

@XmlElement(name = USER_STORE)
private String userStore;

@XmlElementWrapper(name = GROUPS)
@XmlElement(name = GROUP)
private GroupBasicInfo[] groups;

/**
* Creates an instance of the DiscoverableGroup class by parsing an OMElement.
*
* @param discoverableGroupOM The OMElement used to parse and build the DiscoverableGroup object.
* @return A new DiscoverableGroup object populated with data from the OMElement.
*/
public static DiscoverableGroup build(OMElement discoverableGroupOM) {

DiscoverableGroup discoverableGroup = new DiscoverableGroup();
Iterator<?> iter = discoverableGroupOM.getChildElements();
List<GroupBasicInfo> groupList = new ArrayList<>();

while (iter.hasNext()) {
OMElement element = (OMElement) iter.next();
String elementName = element.getLocalName();

if (USER_STORE.equals(elementName) && StringUtils.isNotBlank(element.getText())) {
discoverableGroup.setUserStore(element.getText());
} else if (GROUPS.equals(elementName)) {
Iterator<?> groupIter = element.getChildElements();
while (groupIter.hasNext()) {
OMElement groupElement = (OMElement) groupIter.next();
GroupBasicInfo groupBasicInfo = GroupBasicInfo.build(groupElement);
if (groupBasicInfo != null) {
groupList.add(groupBasicInfo);
}
}
}
}

if (discoverableGroup.getUserStore() == null || groupList.isEmpty()) {
return null;
}

discoverableGroup.setGroups(groupList.toArray(new GroupBasicInfo[0]));
return discoverableGroup;
}

/**
* Get the list of discoverable group basic info for the current user store.
*
* @return The list of group basic info.
*/
public GroupBasicInfo[] getGroups() {

return groups;
}

/**
* Set the list of discoverable group basic info for the current user store.
*
* @param groups The list of group basic info.
*/
public void setGroups(GroupBasicInfo[] groups) {

this.groups = groups;
}

/**
* Get the user store name.
*
* @return The user store name.
*/
public String getUserStore() {

return userStore;
}

/**
* Set the user store name.
*
* @param userStore The user store name.
*/
public void setUserStore(String userStore) {

this.userStore = userStore;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright (c) 2025, 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.application.common.model;

import org.apache.axiom.om.OMElement;
import org.apache.commons.lang.StringUtils;

import java.io.Serializable;
import java.util.Iterator;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
* Basic details of a group for discoverable group list.
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Group")
public class GroupBasicInfo implements Serializable {

private static final long serialVersionUID = -3030000000000000001L;
private static final String ID = "ID";
private static final String NAME = "Name";

@XmlElement(name = ID)
private String id;

@XmlElement(name = NAME)
private String name;

/**
* Creates an instance of the GroupBasicInfo class by parsing an OMElement.
*
* @param groupOM The OMElement used to parse and build the GroupBasicInfo object.
* @return A new GroupBasicInfo object populated with data from the OMElement.
*/
public static GroupBasicInfo build(OMElement groupOM) {

GroupBasicInfo groupBasicInfo = new GroupBasicInfo();
Iterator<?> iter = groupOM.getChildElements();

while (iter.hasNext()) {
OMElement element = (OMElement) iter.next();
String elementName = element.getLocalName();

if (ID.equals(elementName) && StringUtils.isNotBlank(element.getText())) {
groupBasicInfo.setId(element.getText());
} else if (NAME.equals(elementName) && StringUtils.isNotBlank(element.getText())) {
groupBasicInfo.setName(element.getText());
}
}

if (groupBasicInfo.getId() == null) {
return null;
}

return groupBasicInfo;
}

/**
* Get the group ID.
*
* @return Group ID.
*/
public String getId() {

return id;
}

/**
* Set the group ID.
*
* @param id Group ID.
*/
public void setId(String id) {

this.id = id;
}

/**
* Get the group name.
*
* @return Group name.
*/
public String getName() {

return name;
}

/**
* Set the group name.
*
* @param name Group name.
*/
public void setName(String name) {

this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2023, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2014-2025, 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
Expand Down Expand Up @@ -59,6 +59,8 @@ public class ServiceProvider implements Serializable {
private static final String ASSOCIATED_ROLES_CONFIG = "AssociatedRolesConfig";
private static final String IS_API_BASED_AUTHENTICATION_ENABLED = "IsAPIBasedAuthenticationEnabled";
private static final String TRUSTED_APP_METADATA = "TrustedAppMetadata";
private static final String DISCOVERABLE_GROUPS = "DiscoverableGroups";
private static final String DISCOVERABLE_GROUP = "DiscoverableGroup";

@XmlTransient
@JsonIgnore
Expand Down Expand Up @@ -132,6 +134,10 @@ public class ServiceProvider implements Serializable {
@XmlElement(name = "IsDiscoverable")
private boolean isDiscoverable;

@XmlElementWrapper(name = DISCOVERABLE_GROUPS)
@XmlElement(name = DISCOVERABLE_GROUP)
private DiscoverableGroup[] discoverableGroups;

@IgnoreNullElement
@XmlElement(name = TEMPLATE_ID)
private String templateId;
Expand Down Expand Up @@ -305,6 +311,21 @@ public static ServiceProvider build(OMElement serviceProviderOM) {
} else {
serviceProvider.setApplicationEnabled(!"false".equals(element.getText()));
}
} else if (DISCOVERABLE_GROUPS.equals(elementName)) {
Iterator<?> discoverableGroupIter = element.getChildElements();
List<DiscoverableGroup> discoverableGroupList = new ArrayList<>();

while (discoverableGroupIter.hasNext()) {
OMElement discoverableGroupElement = (OMElement) discoverableGroupIter.next();
DiscoverableGroup discoverableGroup = DiscoverableGroup.build(discoverableGroupElement);
if (discoverableGroup != null) {
discoverableGroupList.add(discoverableGroup);
}
}

if (!discoverableGroupList.isEmpty()) {
serviceProvider.setDiscoverableGroups(discoverableGroupList.toArray(new DiscoverableGroup[0]));
}
}
}

Expand Down Expand Up @@ -602,6 +623,26 @@ public void setDiscoverable(boolean discoverable) {
isDiscoverable = discoverable;
}

/**
* Retrieve the list of groups for which the application has been granted discoverable access.
*
* @return The list of discoverable groups.
*/
public DiscoverableGroup[] getDiscoverableGroups() {

return discoverableGroups;
}

/**
* Set the list of groups for which the application has been granted discoverable access.
*
* @param discoverableGroups The list of discoverable groups.
*/
public void setDiscoverableGroups(DiscoverableGroup[] discoverableGroups) {

this.discoverableGroups = discoverableGroups;
}

public String getTemplateId() {

return templateId;
Expand Down
Loading
Loading