Skip to content

Commit

Permalink
imporve the API to include hybrid flow response type
Browse files Browse the repository at this point in the history
  • Loading branch information
asha15 committed Jun 17, 2024
1 parent 6854bf3 commit 43d684e
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ private ApplicationManagementConstants() {
public static final String NON_EXISTING_USER_CODE = "30007 - ";
public static final String APPLICATION_BASED_OUTBOUND_PROVISIONING_ENABLED =
"OutboundProvisioning.enableApplicationBasedOutboundProvisioning";

public static final String CODE_TOKEN = "code token";
public static final String CODE_IDTOKEN = "code id_token";
public static final String CODE_IDTOKEN_TOKEN = "code id_token token";

/**
* Enums for error messages.
Expand Down Expand Up @@ -160,6 +162,13 @@ public enum ErrorMessage {
BLOCK_RENAME_APP_NAME_TO_RESERVED_APP_NAME("60516",
"Renaming application name to a system reserved name is blocked",
"The application name %s is marked as systems reserved application name."),
Hybrid_FLOW_RESPONSE_TYPE_NOT_FOUND("60517",
"Hybrid flow response type not found.",
"Hybrid flow response type cannot be found for the application"),
Hybrid_FLOW_RESPONSE_TYPE_INCORRECT("60518",
"Hybrid flow response type is incorrect.",
"The response type for the hybrid flow should be either 'code token' or 'code id_token' or " +
"'code id_token token'"),

// Server Errors.
ERROR_RETRIEVING_SAML_METADATA("65001",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright (c) 2024, 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.api.server.application.management.v1;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.*;


import io.swagger.annotations.*;
import java.util.Objects;
import javax.validation.Valid;
import javax.xml.bind.annotation.*;

public class HybridFlowConfiguration {

private Boolean enable;
private String responseType;

/**
**/
public HybridFlowConfiguration enable(Boolean enable) {

this.enable = enable;
return this;
}

@ApiModelProperty(example = "true", value = "")
@JsonProperty("enable")
@Valid
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}

/**
**/
public HybridFlowConfiguration responseType(String responseType) {

this.responseType = responseType;
return this;
}

@ApiModelProperty(example = "code id_token", value = "")
@JsonProperty("responseType")
@Valid
public String getResponseType() {
return responseType;
}
public void setResponseType(String responseType) {
this.responseType = responseType;
}



@Override
public boolean equals(java.lang.Object o) {

if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HybridFlowConfiguration hybridFlowConfiguration = (HybridFlowConfiguration) o;
return Objects.equals(this.enable, hybridFlowConfiguration.enable) &&
Objects.equals(this.responseType, hybridFlowConfiguration.responseType);
}

@Override
public int hashCode() {
return Objects.hash(enable, responseType);
}

@Override
public String toString() {

StringBuilder sb = new StringBuilder();
sb.append("class HybridFlowConfiguration {\n");

sb.append(" enable: ").append(toIndentedString(enable)).append("\n");
sb.append(" responseType: ").append(toIndentedString(responseType)).append("\n");
sb.append("}");
return sb.toString();
}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {

if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public static StateEnum fromValue(String value) {

private Boolean publicClient = false;
private OAuth2PKCEConfiguration pkce;
private HybridFlowConfiguration hybridFlow;
private AccessTokenConfiguration accessToken;
private RefreshTokenConfiguration refreshToken;
private IdTokenConfiguration idToken;
Expand Down Expand Up @@ -266,6 +267,24 @@ public void setPkce(OAuth2PKCEConfiguration pkce) {
this.pkce = pkce;
}

/**
**/
public OpenIDConnectConfiguration hybridFlow(HybridFlowConfiguration hybridFlow) {

this.hybridFlow = hybridFlow;
return this;
}

@ApiModelProperty(value = "")
@JsonProperty("hybridFlow")
@Valid
public HybridFlowConfiguration getHybridFlow() {
return hybridFlow;
}
public void setHybridFlow(HybridFlowConfiguration hybridFlow) {
this.hybridFlow = hybridFlow;
}

/**
**/
public OpenIDConnectConfiguration accessToken(AccessTokenConfiguration accessToken) {
Expand Down Expand Up @@ -509,6 +528,7 @@ public boolean equals(java.lang.Object o) {
Objects.equals(this.allowedOrigins, openIDConnectConfiguration.allowedOrigins) &&
Objects.equals(this.publicClient, openIDConnectConfiguration.publicClient) &&
Objects.equals(this.pkce, openIDConnectConfiguration.pkce) &&
Objects.equals(this.hybridFlow, openIDConnectConfiguration.hybridFlow) &&
Objects.equals(this.accessToken, openIDConnectConfiguration.accessToken) &&
Objects.equals(this.refreshToken, openIDConnectConfiguration.refreshToken) &&
Objects.equals(this.idToken, openIDConnectConfiguration.idToken) &&
Expand All @@ -525,7 +545,7 @@ public boolean equals(java.lang.Object o) {

@Override
public int hashCode() {
return Objects.hash(clientId, clientSecret, state, grantTypes, callbackURLs, allowedOrigins, publicClient, pkce, accessToken, refreshToken, idToken, logout, validateRequestObjectSignature, scopeValidators, clientAuthentication, requestObject, pushAuthorizationRequest, subject, isFAPIApplication, fapiMetadata);
return Objects.hash(clientId, clientSecret, state, grantTypes, callbackURLs, allowedOrigins, publicClient, pkce, hybridFlow, accessToken, refreshToken, idToken, logout, validateRequestObjectSignature, scopeValidators, clientAuthentication, requestObject, pushAuthorizationRequest, subject, isFAPIApplication, fapiMetadata);
}

@Override
Expand All @@ -542,6 +562,7 @@ public String toString() {
sb.append(" allowedOrigins: ").append(toIndentedString(allowedOrigins)).append("\n");
sb.append(" publicClient: ").append(toIndentedString(publicClient)).append("\n");
sb.append(" pkce: ").append(toIndentedString(pkce)).append("\n");
sb.append(" hybridFlow: ").append(toIndentedString(hybridFlow)).append("\n");
sb.append(" accessToken: ").append(toIndentedString(accessToken)).append("\n");
sb.append(" refreshToken: ").append(toIndentedString(refreshToken)).append("\n");
sb.append(" idToken: ").append(toIndentedString(idToken)).append("\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
package org.wso2.carbon.identity.api.server.application.management.v1.core.functions.application.inbound.oauth2;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.identity.api.server.application.management.common.ApplicationManagementConstants;
import org.wso2.carbon.identity.api.server.application.management.v1.AccessTokenConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.ClientAuthenticationConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.HybridFlowConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.IdTokenConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.OAuth2PKCEConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.OIDCLogoutConfiguration;
Expand All @@ -28,12 +31,16 @@
import org.wso2.carbon.identity.api.server.application.management.v1.RequestObjectConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.SubjectConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.core.functions.Utils;
import org.wso2.carbon.identity.api.server.common.error.APIError;
import org.wso2.carbon.identity.api.server.common.error.ErrorResponse;
import org.wso2.carbon.identity.oauth.common.OAuthConstants;
import org.wso2.carbon.identity.oauth.dto.OAuthConsumerAppDTO;

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

import javax.ws.rs.core.Response;

import static org.wso2.carbon.identity.api.server.application.management.v1.core.functions.Utils.setIfNotNull;

/**
Expand Down Expand Up @@ -63,6 +70,7 @@ public OAuthConsumerAppDTO apply(String appName, OpenIDConnectConfiguration oidc

updateAllowedOrigins(consumerAppDTO, oidcModel.getAllowedOrigins());
updatePkceConfigurations(consumerAppDTO, oidcModel.getPkce());
updateHybridFlowConfigurations(consumerAppDTO, oidcModel.getHybridFlow());
updateAccessTokenConfiguration(consumerAppDTO, oidcModel.getAccessToken());
updateRefreshTokenConfiguration(consumerAppDTO, oidcModel.getRefreshToken());
updateIdTokenConfiguration(consumerAppDTO, oidcModel.getIdToken());
Expand Down Expand Up @@ -168,6 +176,47 @@ private void updatePkceConfigurations(OAuthConsumerAppDTO consumerAppDTO, OAuth2
}
}

private void updateHybridFlowConfigurations(OAuthConsumerAppDTO consumerAppDTO,
HybridFlowConfiguration hybridFlow) {

if (hybridFlow != null) {

consumerAppDTO.setHybridFlowEnabled(hybridFlow.getEnable());
if (hybridFlow.getEnable()) {
validateHybridFlowResponseType(consumerAppDTO, hybridFlow);
consumerAppDTO.setHybridFlowResponseType(hybridFlow.getResponseType());
}
}
}

private void validateHybridFlowResponseType(OAuthConsumerAppDTO consumerAppDTO,
HybridFlowConfiguration hybridFlowResponseType) {

String[] allowedResponseTypes = {ApplicationManagementConstants.CODE_TOKEN,
ApplicationManagementConstants.CODE_IDTOKEN,
ApplicationManagementConstants.CODE_IDTOKEN_TOKEN};

if (StringUtils.isBlank(hybridFlowResponseType.getResponseType())) {
throw new APIError(Response.Status.BAD_REQUEST,
new ErrorResponse.Builder().withCode(ApplicationManagementConstants.ErrorMessage
.Hybrid_FLOW_RESPONSE_TYPE_NOT_FOUND.getCode())
.withMessage(ApplicationManagementConstants.ErrorMessage
.Hybrid_FLOW_RESPONSE_TYPE_NOT_FOUND.getMessage())
.withDescription(ApplicationManagementConstants.ErrorMessage
.Hybrid_FLOW_RESPONSE_TYPE_NOT_FOUND.getDescription()).build());
}

if (!ArrayUtils.contains(allowedResponseTypes, hybridFlowResponseType.getResponseType())) {
throw new APIError(Response.Status.BAD_REQUEST,
new ErrorResponse.Builder().withCode(ApplicationManagementConstants.ErrorMessage
.Hybrid_FLOW_RESPONSE_TYPE_INCORRECT.getCode())
.withMessage(ApplicationManagementConstants.ErrorMessage
.Hybrid_FLOW_RESPONSE_TYPE_INCORRECT.getMessage())
.withDescription(ApplicationManagementConstants.ErrorMessage
.Hybrid_FLOW_RESPONSE_TYPE_INCORRECT.getDescription()).build());
}
}

private String[] getScopeValidators(OpenIDConnectConfiguration oidcModel) {

return Optional.ofNullable(oidcModel.getScopeValidators())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.identity.api.server.application.management.v1.AccessTokenConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.ClientAuthenticationConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.HybridFlowConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.IdTokenConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.IdTokenEncryptionConfiguration;
import org.wso2.carbon.identity.api.server.application.management.v1.OAuth2PKCEConfiguration;
Expand Down Expand Up @@ -53,6 +54,7 @@ public OpenIDConnectConfiguration apply(OAuthConsumerAppDTO oauthAppDTO) {
.callbackURLs(getCallbackUrls(oauthAppDTO))
.allowedOrigins(getAllowedOrigins(oauthAppDTO))
.pkce(buildPKCEConfiguration(oauthAppDTO))
.hybridFlow(buildHybridFlowConfiguration(oauthAppDTO))
.accessToken(buildTokenConfiguration(oauthAppDTO))
.refreshToken(buildRefreshTokenConfiguration(oauthAppDTO))
.idToken(buildIdTokenConfiguration(oauthAppDTO))
Expand Down Expand Up @@ -86,6 +88,13 @@ private OAuth2PKCEConfiguration buildPKCEConfiguration(OAuthConsumerAppDTO oAuth
.supportPlainTransformAlgorithm(oAuthConsumerAppDTO.getPkceSupportPlain());
}

private HybridFlowConfiguration buildHybridFlowConfiguration(OAuthConsumerAppDTO oAuthConsumerAppDTO) {

return new HybridFlowConfiguration()
.enable(oAuthConsumerAppDTO.isHybridFlowEnabled())
.responseType(oAuthConsumerAppDTO.getHybridFlowResponseType());
}

private AccessTokenConfiguration buildTokenConfiguration(OAuthConsumerAppDTO oAuthConsumerAppDTO) {

return new AccessTokenConfiguration()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3559,6 +3559,8 @@ components:
$ref: '#/components/schemas/OAuth2PKCEConfiguration'
accessToken:
$ref: '#/components/schemas/AccessTokenConfiguration'
hybridFlow:
$ref: '#/components/schemas/HybridFlowConfiguration'
refreshToken:
$ref: '#/components/schemas/RefreshTokenConfiguration'
idToken:
Expand Down Expand Up @@ -3598,6 +3600,15 @@ components:
supportPlainTransformAlgorithm:
type: boolean
example: true
HybridFlowConfiguration:
type: object
properties:
enable:
type: boolean
example: true
responseType:
type: string
example: code id_token
AccessTokenConfiguration:
type: object
properties:
Expand Down

0 comments on commit 43d684e

Please sign in to comment.