Skip to content

Commit

Permalink
feat(jans-config-api): organization configuration management endpoints (
Browse files Browse the repository at this point in the history
#790)

* feat: support jansOrganization config

* feat: jans org endpoint

* feat: organization config endpoint

* feat: jans org management endpoints

* feat: jans orgnanization endpoints

* feat: jans organization endpoint wip

* feat: jans org functionality

* feat: jans org functionality

* feat: jans org manintenance endpoints - wip

* feat: org endpoint

* feat: org endpoints

* feat: org management endpoints

* feat: jans org endpoint management

* feat: jans organization management endpoint
  • Loading branch information
pujavs committed Feb 9, 2022
1 parent 9965250 commit 40ca464
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

public class ApiAccessConstants {

private ApiAccessConstants() {
}

public static final String JANS_AUTH_CONFIG_READ_ACCESS = "https://jans.io/oauth/jans-auth-server/config/properties.readonly";
public static final String JANS_AUTH_CONFIG_WRITE_ACCESS = "https://jans.io/oauth/jans-auth-server/config/properties.write";

Expand Down Expand Up @@ -59,4 +62,7 @@ public class ApiAccessConstants {
public static final String STATS_USER_READ_ACCESS = "https://jans.io/oauth/config/stats.readonly";
public static final String JANS_STAT = "jans_stat";

public static final String ORG_CONFIG_READ_ACCESS = "https://jans.io/oauth/config/organization.readonly";
public static final String ORG_CONFIG_WRITE_ACCESS = "https://jans.io/oauth/config/organization.write";

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
package io.jans.configapi.util;

public class ApiConstants {

private ApiConstants() {}

public static final String BASE_API_URL = "/";
public static final String CONFIG = "/config";
Expand Down Expand Up @@ -69,6 +71,7 @@ public class ApiConstants {
public static final String READY = "/ready";
public static final String STATISTICS = "/stat";
public static final String USER = "/user";
public static final String ORG = "/org";

public static final String LIMIT = "limit";
public static final String START_INDEX = "startIndex";
Expand Down
100 changes: 99 additions & 1 deletion jans-config-api/docs/jans-config-api-swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ tags:
- name: Health - Check
- name: SCIM - User Management
- name: SCIM - Config Management
- name: Organization Configuration
- name: Auth Server Health - Check
- name: Admin UI - Role
- name: Admin UI - Permission
Expand Down Expand Up @@ -2860,6 +2861,59 @@ paths:
'500':
$ref: '#/components/responses/InternalServerError'
/jans-config-api/api/v1/org:
get:
summary: Retrieves organization configuration.
description: Retrieves organization configuration.
operationId: get-organization-config
security:
- oauth2: [https://jans.io/oauth/config/organization.readonly]
tags:
- Organization Configuration
responses:
'200':
description: OK
content:
application/json:
schema:
title: Organization
description: Organization configuration.
$ref: '#/components/schemas/Organization'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
patch:
summary: Partially modifies organization configuration.
description: Partially modifies organization configuration.
operationId: patch-organization-config
security:
- oauth2: [https://jans.io/oauth/config/organization.write]
tags:
- Organization Configuration
requestBody:
content:
application/json-patch+json:
schema:
type: array
items:
$ref: '#/components/schemas/PatchRequest'
description: String representing patch-document.
example: '[{"op": "add", "path": "/jsFaviconPath", "value": "/opt/jans/jetty/jans-auth/custom/static/"}]'
responses:
'200':
description: OK
content:
application/json:
schema:
title: Organization
description: Organization configuration.
$ref: '#/components/schemas/Organization'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
/jans-config-api/api/v1/jans-auth-server/health:
get:
summary: Returns auth server health status.
Expand Down Expand Up @@ -3336,6 +3390,8 @@ components:
https://jans.io/oauth/config/scim/users.write: Manage scim user related information
https://jans.io/scim/config.readonly: Vew SCIM App configuration
https://jans.io/scim/config.write: Manage SCIM App configuration
https://jans.io/oauth/config/organization.readonly: View organization configuration information
https://jans.io/oauth/config/organization.write: Manage organization configuration information

responses:
Found:
Expand Down Expand Up @@ -6543,4 +6599,46 @@ components:
type: boolean
description: Boolean value specifying whether to enable local in-memory cache.
Organization:
type: object
properties:
displayName:
type: string
description: Organization name
description:
type: string
description: Organization description
member:
type: string
description: String describing memberOf
countryName:
type: string
description: Organization country name
organization:
type: string
status:
type: string
managerGroup:
type: string
description: qualified id of the group
example: inum=60B7,ou=groups,o=jans
themeColor:
type: string
description: color of the theme
example: 166309
shortName:
type: string
customMessages:
type: array
items:
type: string
title:
type: string
jsLogoPath:
type: string
description: Path to organization logo image
jsFaviconPath:
type: string
description: Path to organization favicon image

2 changes: 1 addition & 1 deletion jans-config-api/profiles/local/test.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#LOCAL
test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write
test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write

# Test env Setting
#token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public Set<Class<?>> getClasses() {
classes.add(UmaResourcesResource.class);
classes.add(StatResource.class);
classes.add(HealthCheckResource.class);
classes.add(OrganizationResource.class);

return classes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,15 @@ protected static Response getNotAcceptableException(String msg) {

protected static Response getBadRequestException(String msg) {
ApiError error = new ApiError.ErrorBuilder()
.withCode(String.valueOf(Response.Status.NOT_ACCEPTABLE.getStatusCode())).withMessage(msg).build();
.withCode(String.valueOf(Response.Status.BAD_REQUEST.getStatusCode())).withMessage(msg).build();
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}

protected static Response getInternalServerException(String msg) {
ApiError error = new ApiError.ErrorBuilder()
.withCode(String.valueOf(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())).withMessage(msg).build();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}

protected SearchRequest createSearchRequest(String schemas, String filter, String sortBy, String sortOrder,
Integer startIndex, Integer count, String attrsList, String excludedAttrsList) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.configapi.rest.resource.auth;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jsonpatch.JsonPatchException;

import io.jans.as.persistence.model.GluuOrganization;
import io.jans.configapi.service.auth.OrganizationService;
import io.jans.configapi.core.rest.ProtectedApi;
import io.jans.configapi.service.auth.ConfigurationService;
import io.jans.configapi.util.ApiAccessConstants;
import io.jans.configapi.util.ApiConstants;
import io.jans.configapi.core.util.Jackson;

import java.io.IOException;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path(ApiConstants.ORG)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class OrganizationResource extends BaseResource {

@Inject
OrganizationService organizationService;

@GET
@ProtectedApi(scopes = { ApiAccessConstants.ORG_CONFIG_READ_ACCESS })
public Response getOrganization() {
return Response.ok(organizationService.getOrganization()).build();
}

@PATCH
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
@ProtectedApi(scopes = { ApiAccessConstants.ORG_CONFIG_WRITE_ACCESS })
public Response patchOrganization(@NotNull String pathString) throws JsonPatchException, IOException {
log.trace("Organization patch request - pathString:{} ", pathString);
GluuOrganization organization = organizationService.getOrganization();
organization = Jackson.applyPatch(pathString, organization);
organizationService.updateOrganization(organization);
return Response.ok(organizationService.getOrganization()).build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public String getIssuer() {
return this.configurationService.find().getIssuer();
}

public String getServiceUrl(String url) {
return this.getIssuer() + url;
}

public String getClientId() {
return this.configurationFactory.getApiClientId();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,23 @@
]
}
]
},
{
"path":"/jans-config-api/api/v1/org",
"conditions":[
{
"httpMethods":["GET"],
"scopes":[
"https://jans.io/oauth/config/organization.readonly"
]
},
{
"httpMethods":["PATCH"],
"scopes":[
"https://jans.io/oauth/config/organization.write"
]
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

Feature: Verify Organization configuration endpoint

Background:
* def mainUrl = org_configuration_url

@auth-config-get-error
Scenario: Retrieve Organization configuration without bearer token
Given url mainUrl
When method GET
Then status 401
And print response

@auth-config-get
Scenario: Retrieve Organization configuration
Given url mainUrl
And header Authorization = 'Bearer ' + accessToken
When method GET
Then status 200
And print response
And assert response.length != null

@auth-config-patch
Scenario: Patch Organization configuration
Given url mainUrl
And header Authorization = 'Bearer ' + accessToken
When method GET
Then status 200
And print response
And assert response.length != null
Given url mainUrl
And header Authorization = 'Bearer ' + accessToken
And header Content-Type = 'application/json-patch+json'
And header Accept = 'application/json'
And print response.description
#And def request_body = (response.description == null ? "[ {\"op\":\"add\", \"path\": \"/description\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":"+response.description+" } ]")
And def request_body = (response.description == null ? "[ {\"op\":\"add\", \"path\": \"/description\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":\""+response.description+"\" } ]")
And print request_body
And request request_body
Then print request
When method PATCH
Then status 200
And print response


Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function() {
smtp_url: baseUrl + '/jans-config-api/api/v1/config/smtp',
logging_url: baseUrl + '/jans-config-api/api/v1/logging',
auth_health_url: baseUrl + '/jans-config-api/api/v1/jans-auth-server/health',
org_configuration_url: baseUrl + '/jans-config-api/api/v1/org',
};

karate.configure('connectTimeout', 30000);
Expand Down
1 change: 1 addition & 0 deletions jans-config-api/server/src/test/resources/karate-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function() {
smtp_url: baseUrl + '/jans-config-api/api/v1/config/smtp',
logging_url: baseUrl + '/jans-config-api/api/v1/logging',
auth_health_url: baseUrl + '/jans-config-api/api/v1/jans-auth-server/health',
org_configuration_url: baseUrl + '/jans-config-api/api/v1/org',
};

karate.configure('connectTimeout', 30000);
Expand Down

0 comments on commit 40ca464

Please sign in to comment.