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

Add support for rich authorization requests #2511

Merged
merged 29 commits into from
Jan 23, 2025
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c8d568e
accept and persist authorization_details of authorize request
VimukthiRajapaksha Jul 2, 2024
f7544ce
Accept and persist authorization_details of token request
VimukthiRajapaksha Jul 26, 2024
dd8f27f
resolve merge conflicts
VimukthiRajapaksha Jul 31, 2024
824163c
Add unit tests for the rar module
VimukthiRajapaksha Aug 7, 2024
3360d4e
Merge remote-tracking branch 'origin/master' into master_rar
VimukthiRajapaksha Aug 7, 2024
3031c32
Add unit tests
VimukthiRajapaksha Sep 3, 2024
376e5cc
Fix merge conflicts
VimukthiRajapaksha Sep 3, 2024
b12db7c
Add schema validation
VimukthiRajapaksha Oct 8, 2024
8256664
Merge branch 'master' into master_rar
VimukthiRajapaksha Oct 8, 2024
c3c9fe9
Add unit tests to discovery endpoint
VimukthiRajapaksha Oct 9, 2024
7e5ac32
Change schema type to CLOB
VimukthiRajapaksha Oct 25, 2024
d5249a2
Resolve merge conflicts
VimukthiRajapaksha Oct 25, 2024
ca2f054
Resolve merge conflicts
VimukthiRajapaksha Oct 28, 2024
9c8fe25
Resolve merge conflicts
VimukthiRajapaksha Oct 28, 2024
ffba19a
Add license headers
VimukthiRajapaksha Oct 28, 2024
4c56858
Add a config method to check if RAR is enabled
VimukthiRajapaksha Nov 13, 2024
7a90b09
Resolve merge conflicts
VimukthiRajapaksha Nov 13, 2024
faa5e31
Fix refresh token introspection issue
VimukthiRajapaksha Nov 13, 2024
4a156b2
Resolve merge conflicts
VimukthiRajapaksha Dec 18, 2024
bc0ac7d
resolve merge conflicts
VimukthiRajapaksha Jan 9, 2025
95792de
Resolve test failures
VimukthiRajapaksha Jan 17, 2025
d5fde99
Merge remote-tracking branch 'origin/master' into master_rar
VimukthiRajapaksha Jan 17, 2025
61bf493
Improve unit tests coverage
VimukthiRajapaksha Jan 17, 2025
f523061
bump carbon.identity.framework.version to support authorization details
VimukthiRajapaksha Jan 17, 2025
be2070a
Add logic to check RAR is enabled
VimukthiRajapaksha Jan 17, 2025
0c03aa3
Update license to 2025
VimukthiRajapaksha Jan 17, 2025
7cf9f62
Change org.wso2.carbon.identity.oauth.rar packaging type to bundle
VimukthiRajapaksha Jan 22, 2025
0a80f81
Merge remote-tracking branch 'origin/master' into master_rar
VimukthiRajapaksha Jan 22, 2025
4959016
Bump RAR version to 7.0.219-SNAPSHOT
VimukthiRajapaksha Jan 23, 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
Prev Previous commit
Next Next commit
Add unit tests for the rar module
VimukthiRajapaksha committed Aug 7, 2024
commit 824163c0d3fffeccb7bfe1e6d09c471782de863e
106 changes: 104 additions & 2 deletions components/org.wso2.carbon.identity.oauth.rar/pom.xml
Original file line number Diff line number Diff line change
@@ -55,11 +55,32 @@
<scope>provided</scope>
</dependency>

<!--Test Dependencies-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-testng</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
@@ -80,6 +101,87 @@
<maxHeap>2048</maxHeap>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
<reuseForks>true</reuseForks>
</configuration>
</plugin>

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!--Excluding them in coverage reports-->
<exclude>**/*Constants.class</exclude>
<exclude>**/model/**</exclude>
<exclude>**/dto/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-instrument</id>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>default-restore-instrumented-classes</id>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>

Original file line number Diff line number Diff line change
@@ -100,19 +100,22 @@ public Set<AuthorizationDetailsConsentDTO> getUserConsentedAuthorizationDetails(
public int[] updateUserConsentedAuthorizationDetails(
final List<AuthorizationDetailsConsentDTO> authorizationDetailsConsentDTOs) throws SQLException {

try (final Connection connection = IdentityDatabaseUtil.getDBConnection(false);
final PreparedStatement ps =
connection.prepareStatement(SQLQueries.UPDATE_OAUTH2_USER_CONSENTED_AUTHORIZATION_DETAILS)) {
// todo: This won't update the expected element. Hence, need to revisit the update logic
return null;

for (AuthorizationDetailsConsentDTO consentDTO : authorizationDetailsConsentDTOs) {
ps.setString(1, consentDTO.getAuthorizationDetail().toJsonString());
ps.setBoolean(2, consentDTO.isConsentActive());
ps.setString(3, consentDTO.getConsentId());
ps.setInt(4, consentDTO.getTenantId());
ps.addBatch();
}
return ps.executeBatch();
}
// try (final Connection connection = IdentityDatabaseUtil.getDBConnection(false);
// final PreparedStatement ps =
// connection.prepareStatement(SQLQueries.UPDATE_OAUTH2_USER_CONSENTED_AUTHORIZATION_DETAILS)) {
//
// for (AuthorizationDetailsConsentDTO consentDTO : authorizationDetailsConsentDTOs) {
// ps.setString(1, consentDTO.getAuthorizationDetail().toJsonString());
// ps.setBoolean(2, consentDTO.isConsentActive());
// ps.setString(3, consentDTO.getConsentId());
// ps.setInt(4, consentDTO.getTenantId());
// ps.addBatch();
// }
// return ps.executeBatch();
// }
}

/**
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.wso2.carbon.identity.oauth2.rar.dao;

import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.oauth2.rar.dto.AuthorizationDetailsConsentDTO;
import org.wso2.carbon.identity.oauth2.rar.dto.AuthorizationDetailsTokenDTO;
import org.wso2.carbon.identity.oauth2.rar.model.AuthorizationDetail;
import org.wso2.carbon.identity.oauth2.rar.util.DAOUtils;

import java.sql.SQLException;
import java.util.Collections;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;

public class AuthorizationDetailsDAOImplTest {

private static final String TEST_CONSENT_ID = "52481ccd-0927-4d17-8cfc-5110fc4aa009";
private static final String TEST_DB_NAME = "TEST_IAM_RAR_DATABASE";
private static final int TEST_TENANT_ID = 1234;
private static final String TEST_TOKEN_ID = "e1fea951-a3b5-4347-bd73-b18b3feecd54";
private static final String TEST_TYPE = "test_type_v1";

private MockedStatic<IdentityDatabaseUtil> identityDatabaseUtilMock;
private AuthorizationDetailsDAO uut;

@BeforeClass
public void setUp() throws SQLException {
this.uut = new AuthorizationDetailsDAOImpl();
DAOUtils.initializeDataSource(TEST_DB_NAME, DAOUtils.getFilePath("h2.sql"));
this.identityDatabaseUtilMock = Mockito.mockStatic(IdentityDatabaseUtil.class);
}

@AfterClass
public void tearDown() throws SQLException {

if (this.identityDatabaseUtilMock != null && !this.identityDatabaseUtilMock.isClosed()) {
this.identityDatabaseUtilMock.close();
}
}

@BeforeMethod
public void setUpBeforeMethod() throws SQLException {
this.identityDatabaseUtilMock
.when(() -> IdentityDatabaseUtil.getDBConnection(any(Boolean.class)))
.thenReturn(DAOUtils.getConnection(TEST_DB_NAME));
}

@Test(priority = 0)
public void testAddUserConsentedAuthorizationDetails() throws SQLException {

assertEquals(0, this.uut.getUserConsentedAuthorizationDetails(TEST_CONSENT_ID, TEST_TENANT_ID).size());

this.identityDatabaseUtilMock
.when(() -> IdentityDatabaseUtil.getDBConnection(any(Boolean.class)))
.thenReturn(DAOUtils.getConnection(TEST_DB_NAME));

AuthorizationDetail testAuthorizationDetail = new AuthorizationDetail();
testAuthorizationDetail.setType(TEST_TYPE);

AuthorizationDetailsConsentDTO consentDTO =
new AuthorizationDetailsConsentDTO(TEST_CONSENT_ID, testAuthorizationDetail, true, TEST_TENANT_ID);
int[] result = uut.addUserConsentedAuthorizationDetails(Collections.singletonList(consentDTO));

assertEquals(1, result.length);
}

@Test(priority = 1)
public void testGetUserConsentedAuthorizationDetails() throws SQLException {

Set<AuthorizationDetailsConsentDTO> consentDTOs =
this.uut.getUserConsentedAuthorizationDetails(TEST_CONSENT_ID, TEST_TENANT_ID);

assertEquals(1, consentDTOs.size());
consentDTOs.forEach(dto -> {
assertEquals(TEST_CONSENT_ID, dto.getConsentId());
assertNotNull(dto.getAuthorizationDetail());
assertEquals(TEST_TYPE, dto.getAuthorizationDetail().getType());
});
}

@Test(priority = 2)
public void testDeleteUserConsentedAuthorizationDetails() throws SQLException {

assertEquals(1, uut.deleteUserConsentedAuthorizationDetails(TEST_CONSENT_ID, TEST_TENANT_ID));

this.identityDatabaseUtilMock
.when(() -> IdentityDatabaseUtil.getDBConnection(any(Boolean.class)))
.thenReturn(DAOUtils.getConnection(TEST_DB_NAME));

assertEquals(0, this.uut.getUserConsentedAuthorizationDetails(TEST_CONSENT_ID, TEST_TENANT_ID).size());
}

@Test(priority = 0)
public void testAddAccessTokenAuthorizationDetails() throws SQLException {
assertEquals(0, this.uut.getAccessTokenAuthorizationDetails(TEST_TOKEN_ID, TEST_TENANT_ID).size());

this.identityDatabaseUtilMock
.when(() -> IdentityDatabaseUtil.getDBConnection(any(Boolean.class)))
.thenReturn(DAOUtils.getConnection(TEST_DB_NAME));

AuthorizationDetail testAuthorizationDetail = new AuthorizationDetail();
testAuthorizationDetail.setType(TEST_TYPE);

AuthorizationDetailsTokenDTO tokenDTO =
new AuthorizationDetailsTokenDTO(TEST_TOKEN_ID, testAuthorizationDetail, TEST_TENANT_ID);

int[] result = uut.addAccessTokenAuthorizationDetails(Collections.singletonList(tokenDTO));

assertEquals(1, result.length);
}

@Test(priority = 1)
public void testGetAccessTokenAuthorizationDetails() throws SQLException {
Set<AuthorizationDetailsTokenDTO> tokenDTOs =
this.uut.getAccessTokenAuthorizationDetails(TEST_TOKEN_ID, TEST_TENANT_ID);

assertEquals(1, tokenDTOs.size());
tokenDTOs.forEach(dto -> {
assertEquals(TEST_TOKEN_ID, dto.getAccessTokenId());
assertNotNull(dto.getAuthorizationDetail());
assertEquals(TEST_TYPE, dto.getAuthorizationDetail().getType());
});
}

@Test(priority = 2)
public void testDeleteAccessTokenAuthorizationDetails() throws SQLException {
assertEquals(1, uut.deleteAccessTokenAuthorizationDetails(TEST_TOKEN_ID, TEST_TENANT_ID));

this.identityDatabaseUtilMock
.when(() -> IdentityDatabaseUtil.getDBConnection(any(Boolean.class)))
.thenReturn(DAOUtils.getConnection(TEST_DB_NAME));

assertEquals(0, this.uut.getAccessTokenAuthorizationDetails(TEST_TOKEN_ID, TEST_TENANT_ID).size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package org.wso2.carbon.identity.oauth2.rar.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.mockito.Mockito;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.collections.Sets;
import org.wso2.carbon.identity.oauth2.rar.model.AuthorizationDetail;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;

/**
* Test class for {@link AuthorizationDetailsCommonUtils}.
*/
public class AuthorizationDetailsCommonUtilsTest {

private ObjectMapper objectMapper;
private ObjectMapper mockObjectMapper;
private static final String TEST_TYPE = "test_type_v1";

@BeforeClass
public void setUp() throws JsonProcessingException {

this.objectMapper = AuthorizationDetailsCommonUtils.getDefaultObjectMapper();
this.mockObjectMapper = Mockito.spy(this.objectMapper);

// mock
doThrow(JsonProcessingException.class)
.when(this.mockObjectMapper).writeValueAsString(any(TestAuthorizationDetail.class));
doThrow(JsonProcessingException.class).when(this.mockObjectMapper).writeValueAsString(any(Set.class));
}

@DataProvider(name = "AuthorizationDetailsCommonUtilsTestDataProvider")
public Object[][] provideAuthorizationDetailsCommonUtilsTestData(Method testMethod) {

switch (testMethod.getName()) {
case "shouldReturnNull_whenJSONIsInvalid":
case "shouldReturnCorrectSize_whenJSONArrayIsValid":
return new Object[][]{
{null, 0},
{"", 0},
{" ", 0},
{"invalid JSON", 0},
{"[]", 0},
{"[{}]", 1},
{"[{},{}]", 2}
};
case "shouldReturnCorrectType_whenJSONIsValid":
return new Object[][]{
{AuthorizationDetail.class},
{TestAuthorizationDetail.class}
};
}
return null;
}

@Test(dataProvider = "AuthorizationDetailsCommonUtilsTestDataProvider")
public void shouldReturnCorrectSize_whenJSONArrayIsValid(String inputJson, int expectedSize) {

Set<AuthorizationDetail> actualAuthorizationDetails = AuthorizationDetailsCommonUtils
.fromJSONArray(inputJson, AuthorizationDetail.class, objectMapper);

assertEquals(expectedSize, actualAuthorizationDetails.size());
}

@Test(dataProvider = "AuthorizationDetailsCommonUtilsTestDataProvider")
public void shouldReturnNull_whenJSONIsInvalid(String inputJson, int expectedSize) {

assertNull(AuthorizationDetailsCommonUtils.fromJSON(inputJson, AuthorizationDetail.class, objectMapper));
}

@Test(dataProvider = "AuthorizationDetailsCommonUtilsTestDataProvider")
public <T extends AuthorizationDetail> void shouldReturnCorrectType_whenJSONIsValid(Class<T> expectedClazz) {

final String inputJson = "{\"type\": \"" + TEST_TYPE + "\"}";
AuthorizationDetail actualAuthorizationDetail =
AuthorizationDetailsCommonUtils.fromJSON(inputJson, expectedClazz, objectMapper);

assertNotNull(actualAuthorizationDetail);
assertEquals(TEST_TYPE, actualAuthorizationDetail.getType());
}

@Test
public void shouldReturnCorrectJson_whenAuthorizationDetailsAreValid() {

AuthorizationDetail inputAuthorizationDetail = new TestAuthorizationDetail();
inputAuthorizationDetail.setType(TEST_TYPE);

assertTrue(AuthorizationDetailsCommonUtils.toJSON(Sets.newHashSet(inputAuthorizationDetail), objectMapper)
.contains(TEST_TYPE));
assertEquals("[]", AuthorizationDetailsCommonUtils.toJSON((Set<AuthorizationDetail>) null, objectMapper));
assertEquals("[]",
AuthorizationDetailsCommonUtils.toJSON(Sets.newHashSet(inputAuthorizationDetail), mockObjectMapper));
}

@Test
public void shouldReturnCorrectJson_whenAuthorizationDetailIsValid() {

AuthorizationDetail inputAuthorizationDetail = new TestAuthorizationDetail();
inputAuthorizationDetail.setType(TEST_TYPE);

assertTrue(AuthorizationDetailsCommonUtils.toJSON(inputAuthorizationDetail, objectMapper).contains(TEST_TYPE));
assertEquals("{}", AuthorizationDetailsCommonUtils.toJSON((TestAuthorizationDetail) null, objectMapper));
assertEquals("{}", AuthorizationDetailsCommonUtils.toJSON(new TestAuthorizationDetail(), mockObjectMapper));
}

@Test
public void shouldReturnMap_whenAuthorizationDetailIsValid() {

AuthorizationDetail inputAuthorizationDetail = new TestAuthorizationDetail();
inputAuthorizationDetail.setType(TEST_TYPE);
Map<String, Object> actualMap = AuthorizationDetailsCommonUtils.toMap(inputAuthorizationDetail, objectMapper);

assertTrue(actualMap.containsKey("type"));
assertEquals(TEST_TYPE, String.valueOf(actualMap.get("type")));
assertEquals(1, actualMap.keySet().size());

assertFalse(AuthorizationDetailsCommonUtils.toMap(null, objectMapper).containsKey(TEST_TYPE));
}

private static class TestAuthorizationDetail extends AuthorizationDetail {
// Test authorization detail class which extends AuthorizationDetail
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.wso2.carbon.identity.oauth2.rar.util;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang.StringUtils;

import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
* DB Utils.
*/
public class DAOUtils {

private static final Map<String, BasicDataSource> dataSourceMap = new HashMap<>();

public static void initializeDataSource(String databaseName, String scriptPath) throws SQLException {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setUrl("jdbc:h2:mem:" + databaseName);

try (Connection connection = dataSource.getConnection()) {
connection.createStatement().executeUpdate("RUNSCRIPT FROM '" + scriptPath + "'");
}
dataSourceMap.put(databaseName, dataSource);
}

public static Connection getConnection(String database) throws SQLException {
if (dataSourceMap.get(database) != null) {
return dataSourceMap.get(database).getConnection();
}
throw new RuntimeException("Invalid datasource.");
}

public static String getFilePath(String fileName) {
if (StringUtils.isNotBlank(fileName)) {
return Paths.get(System.getProperty("user.dir"), "src", "test", "resources", "dbScripts", fileName)
.toString();
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
CREATE TABLE IF NOT EXISTS IDN_OAUTH2_AUTHORIZATION_DETAILS_TYPES(
ID INTEGER NOT NULL AUTO_INCREMENT,
TYPE VARCHAR(255) NOT NULL,
CURSOR_KEY INTEGER DEFAULT 1,
NAME VARCHAR(255),
DESCRIPTION VARCHAR (255),
JSON_SCHEMA JSON NOT NULL,
TENANT_ID INTEGER DEFAULT -1
);

CREATE TABLE IF NOT EXISTS IDN_OAUTH2_USER_CONSENTED_AUTHORIZATION_DETAILS (
ID INTEGER NOT NULL AUTO_INCREMENT,
CONSENT_ID VARCHAR(255) NOT NULL,
TYPE_ID INTEGER NOT NULL,
AUTHORIZATION_DETAILS JSON NOT NULL,
CONSENT BOOLEAN NOT NULL DEFAULT 1,
TENANT_ID INTEGER NOT NULL DEFAULT -1
);

CREATE TABLE IF NOT EXISTS IDN_OAUTH2_ACCESS_TOKEN_AUTHORIZATION_DETAILS (
ID INTEGER NOT NULL AUTO_INCREMENT,
TYPE_ID INTEGER NOT NULL,
AUTHORIZATION_DETAILS JSON NOT NULL,
TOKEN_ID VARCHAR (255),
TENANT_ID INTEGER DEFAULT -1
);

INSERT INTO IDN_OAUTH2_AUTHORIZATION_DETAILS_TYPES (TYPE, NAME, DESCRIPTION, JSON_SCHEMA, TENANT_ID)
VALUES ('test_type_v1', 'Test Type', 'Test Type V1', '{}', 1234);
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!--
~ Copyright (c) 2024, WSO2 LLC. (https://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.
-->
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="oauth-rar-test-suite" verbose="1">

<test name="oauth-rar-test">
<classes>
<class name="org.wso2.carbon.identity.oauth2.rar.util.AuthorizationDetailsCommonUtilsTest"/>
<class name="org.wso2.carbon.identity.oauth2.rar.dao.AuthorizationDetailsDAOImplTest"/>
</classes>
</test>

</suite>