Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -27,6 +27,8 @@ private Constants() {

public static final String AUTHENTICATOR_ERROR_PREFIX = "AUT-";
public static final String FEDERATED_AUTHENTICATORS = "federatedAuthenticators";
// IdP property marking a shadow (shared) connection resolved from a parent organization.
public static final String IS_SHARED_PROPERTY = "isShared";
public static final String AUTHENTICATOR_PATH_COMPONENT = "/authenticators";
public static final String CONFIGS_AUTHENTICATOR_PATH_COMPONENT = "/configs/authenticators/%s";
public static final String PATH_SEPERATOR = "/";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class Authenticator {
private String name;
private String displayName;
private Boolean isEnabled;
private Boolean isShared;

@XmlType(name="DefinedByEnum")
@XmlEnum(String.class)
Expand Down Expand Up @@ -182,6 +183,25 @@ public void setIsEnabled(Boolean isEnabled) {
this.isEnabled = isEnabled;
}

/**
* Whether this authenticator belongs to a shared connection resolved from a parent organization.
**/
public Authenticator isShared(Boolean isShared) {

this.isShared = isShared;
return this;
}

@ApiModelProperty(example = "false", value = "Whether this authenticator belongs to a shared connection resolved from a parent organization.")
@JsonProperty("isShared")
@Valid
public Boolean getIsShared() {
return isShared;
}
public void setIsShared(Boolean isShared) {
this.isShared = isShared;
}

/**
**/
public Authenticator definedBy(DefinedByEnum definedBy) {
Expand Down Expand Up @@ -314,6 +334,7 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.name, authenticator.name) &&
Objects.equals(this.displayName, authenticator.displayName) &&
Objects.equals(this.isEnabled, authenticator.isEnabled) &&
Objects.equals(this.isShared, authenticator.isShared) &&
Objects.equals(this.definedBy, authenticator.definedBy) &&
Objects.equals(this.type, authenticator.type) &&
Objects.equals(this.image, authenticator.image) &&
Expand All @@ -324,7 +345,7 @@ public boolean equals(java.lang.Object o) {

@Override
public int hashCode() {
return Objects.hash(id, name, displayName, isEnabled, definedBy, type, image, description, tags, self);
return Objects.hash(id, name, displayName, isEnabled, isShared, definedBy, type, image, description, tags, self);
}

@Override
Expand All @@ -337,6 +358,7 @@ public String toString() {
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" displayName: ").append(toIndentedString(displayName)).append("\n");
sb.append(" isEnabled: ").append(toIndentedString(isEnabled)).append("\n");
sb.append(" isShared: ").append(toIndentedString(isShared)).append("\n");
sb.append(" definedBy: ").append(toIndentedString(definedBy)).append("\n");
sb.append(" type: ").append(toIndentedString(type)).append("\n");
sb.append(" image: ").append(toIndentedString(image)).append("\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.wso2.carbon.identity.application.common.exception.AuthenticatorMgtServerException;
import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.model.IdentityProviderProperty;
import org.wso2.carbon.identity.application.common.model.LocalAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.RequestPathAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.UserDefinedLocalAuthenticatorConfig;
Expand All @@ -63,6 +64,7 @@
import org.wso2.carbon.idp.mgt.IdpManager;
import org.wso2.carbon.idp.mgt.model.ConnectedAppsResult;
import org.wso2.carbon.idp.mgt.model.IdpSearchResult;
import org.wso2.carbon.idp.mgt.model.SharedIdPResolveType;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
Expand Down Expand Up @@ -155,7 +157,8 @@ public List<Authenticator> getAuthenticators(String filter, Integer limit, Integ
at the maximum items per page count. */
if (idPCountToBeRetrieved > 0 && StringUtils.isBlank(filter)) {
IdpSearchResult idpSearchResult = idpManager.getIdPs(idPCountToBeRetrieved, null, null,
null, null, ContextLoader.getTenantDomainFromContext(), requestedAttributeList);
null, null, ContextLoader.getTenantDomainFromContext(), requestedAttributeList,
SharedIdPResolveType.BASE_PARENT);
identityProviders = idpSearchResult.getIdPs();
}

Expand Down Expand Up @@ -401,7 +404,7 @@ private List<Authenticator> buildAuthenticatorsListResponse(String filter, List<
try {
idpSearchResult = idpManager.getIdPs(idPCountToBeRetrieved, null, null, null,
ContextLoader.getTenantDomainFromContext(), requestedAttributeList,
expressionNodesForIdp);
expressionNodesForIdp, SharedIdPResolveType.BASE_PARENT);
identityProviders = idpSearchResult.getIdPs();
if (identityProviders != null) {
addIdPsToAuthenticatorList(maximumItemsPerPage, identityProviders, authenticators,
Expand Down Expand Up @@ -504,6 +507,7 @@ private void addIdp(IdentityProvider identityProvider, List<Authenticator> authe
authenticator.setDisplayName(identityProvider.getIdentityProviderName());
}
authenticator.setIsEnabled(identityProvider.isEnable());
authenticator.setIsShared(resolveIsSharedConnection(identityProvider));
authenticator.setType(Authenticator.TypeEnum.FEDERATED);
authenticator.setImage(identityProvider.getImageUrl());
authenticator.setDescription(identityProvider.getIdentityProviderDescription());
Expand Down Expand Up @@ -531,6 +535,28 @@ private void addIdp(IdentityProvider identityProvider, List<Authenticator> authe
String.format("/v1/identity-providers/%s", identityProvider.getResourceId())).toString());
}

/**
* Resolves the value of the {@code isShared} IdP property when it is present on the identity provider (i.e. it
* belongs to a shared/shadow connection resolved from a parent organization), or {@code null} when the property
* is absent — so the {@code isShared} attribute is emitted only for shared connections and omitted otherwise.
*
* @param identityProvider The identity provider.
* @return The {@code isShared} property value if present; {@code null} otherwise.
*/
private Boolean resolveIsSharedConnection(IdentityProvider identityProvider) {

IdentityProviderProperty[] idpProperties = identityProvider.getIdpProperties();
if (idpProperties == null) {
return null;
}
for (IdentityProviderProperty property : idpProperties) {
if (Constants.IS_SHARED_PROPERTY.equals(property.getName())) {
return Boolean.parseBoolean(property.getValue());
}
}
return null;
}

private FederatedAuthenticatorConfig resolveFederatedAuthenticatorConfig(IdentityProvider identityProvider) {

try {
Expand Down Expand Up @@ -892,7 +918,8 @@ private void getFilteredIdPs(int limit, int offSet, List<String> requestedAttrib

try {
IdpSearchResult idpSearchResult = idpManager.getIdPs(limit, (offSet + limit), null, null,
ContextLoader.getTenantDomainFromContext(), requestedAttributeList, expressionNodes);
ContextLoader.getTenantDomainFromContext(), requestedAttributeList, expressionNodes,
SharedIdPResolveType.BASE_PARENT);
identityProviders.addAll(idpSearchResult.getIdPs());
} catch (IdentityProviderManagementException e) {
throw handleIdPException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_LISTING_IDPS, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ components:
isEnabled:
type: boolean
example: true
isShared:
type: boolean
example: true
description: Whether this authenticator belongs to a shared connection resolved from a parent organization.
Present (and true) only for shared connections; omitted otherwise.
readOnly: true
definedBy:
type: string
enum:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
<artifactId>org.wso2.carbon.identity.template.mgt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.organization.management</groupId>
<artifactId>org.wso2.carbon.identity.organization.management.organization.connection.sharing</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class Constants {
public static final String JWKS_URI = "jwksUri";
public static final String SAML_METADATA_URI = "samlMetadataUri";
public static final String IDP_ISSUER_NAME = "idpIssuerName";
// IdP property marking a shadow (shared) connection resolved from a parent organization.
public static final String IS_SHARED_PROPERTY = "isShared";
public static final String TEMPLATE_ID = "templateId";
public static final String META_DATA_SAML = "meta_data_saml";
public static final String SELECT_MODE = "SelectMode";
Expand Down Expand Up @@ -63,6 +65,19 @@ public class Constants {
public static final String PAGE_LINK_REL_NEXT = "next";
public static final String PAGE_LINK_REL_PREVIOUS = "previous";

// IdP sharing constants.
public static final String IDP_SHARE_PATH_COMPONENT = "/share";
public static final String LIMIT_PARAM = "limit";
public static final String RECURSIVE_PARAM = "recursive";
public static final String FILTER_PARAM = "filter";
public static final String EXCLUDED_ATTRIBUTES_PARAM = "excludedAttributes";
public static final String INCLUDED_ATTRIBUTES_PARAM = "attributes";
public static final String ASYNC_OPERATION_RESPONSE_STATUS = "Processing";
public static final String IDP_SHARE_TRIGGER_SUCCESS =
"Identity provider sharing process triggered successfully.";
public static final String IDP_UNSHARE_TRIGGER_SUCCESS =
"Identity provider unsharing process triggered successfully.";

// IdP attributes constants.
public static final String IS_PRIMARY = "isPrimary";
public static final String IS_FEDERATION_HUB = "isFederationHub";
Expand Down Expand Up @@ -170,6 +185,18 @@ public enum ErrorMessage {
"Maximum number of authenticator properties exceeded.",
"Maximum number of allowed properties for a federated authenticator have been exceeded. " +
"Max allowed: %s."),
ERROR_CODE_INVALID_SHARE_REQUEST_BODY("60046",
"Invalid identity provider share request body.",
"The request body of the identity provider sharing request is empty or invalid."),
ERROR_CODE_SHARE_REQUEST_NO_ORGANIZATIONS("60047",
"No organizations provided.",
"At least one organization must be provided for the identity provider sharing/unsharing operation."),
ERROR_CODE_UNSUPPORTED_SHARE_POLICY("60048",
"Unsupported sharing policy.",
"Provided sharing policy %s is not supported for this operation."),
ERROR_CODE_INVALID_PAGINATION_CURSOR("60049",
"Invalid pagination cursor.",
"Provided pagination cursor is invalid."),

// Server Error starting from 650xx.
ERROR_CODE_ERROR_ADDING_IDP("65002",
Expand Down Expand Up @@ -288,7 +315,15 @@ public enum ErrorMessage {
ERROR_CODE_ERROR_INVALID_SEARCH_FILTER("65055", "Search request validation failed.",
"Invalid search filter."),
ERROR_CODE_VALIDATING_LOCAL_CLAIM_URIS("65056", "Error while validation local claim URIs",
"Error while validating claim URIs against local claims");
"Error while validating claim URIs against local claims"),
ERROR_CODE_ERROR_SHARING_IDP("65057", "Unable to share the identity provider.",
"Server encountered an error while sharing the identity provider."),
ERROR_CODE_ERROR_UNSHARING_IDP("65058", "Unable to unshare the identity provider.",
"Server encountered an error while unsharing the identity provider."),
ERROR_CODE_ERROR_RETRIEVING_SHARED_ORGS("65059",
"Unable to retrieve the organizations the identity provider is shared with.",
"Server encountered an error while retrieving the organizations the identity provider " +
"is shared with.");

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService;
import org.wso2.carbon.identity.organization.management.organization.connection.sharing.ConnectionSharingPolicyHandlerService;
import org.wso2.carbon.identity.template.mgt.TemplateManager;
import org.wso2.carbon.idp.mgt.IdentityProviderManager;

Expand Down Expand Up @@ -49,6 +50,13 @@ private static class TemplateManagerHolder {
.getThreadLocalCarbonContext().getOSGiService(TemplateManager.class, null);
}

private static class ConnectionSharingPolicyHandlerServiceHolder {

static final ConnectionSharingPolicyHandlerService SERVICE =
(ConnectionSharingPolicyHandlerService) PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getOSGiService(ConnectionSharingPolicyHandlerService.class, null);
}

/**
* Get IdentityProviderManager osgi service.
*
Expand Down Expand Up @@ -78,4 +86,14 @@ public static TemplateManager getTemplateManager() {

return TemplateManagerHolder.SERVICE;
}

/**
* Get ConnectionSharingPolicyHandlerService osgi service.
*
* @return ConnectionSharingPolicyHandlerService.
*/
public static ConnectionSharingPolicyHandlerService getConnectionSharingPolicyHandlerService() {

return ConnectionSharingPolicyHandlerServiceHolder.SERVICE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,21 @@
<artifactId>cxf-rt-rs-extension-search</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.organization.management.core</groupId>
<artifactId>org.wso2.carbon.identity.organization.management.service</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.organization.management</groupId>
<artifactId>org.wso2.carbon.identity.organization.management.organization.connection.sharing</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.organization.management</groupId>
<artifactId>org.wso2.carbon.identity.organization.resource.sharing.policy.management</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
Expand Down
Loading
Loading