Skip to content
Closed
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
11 changes: 11 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ jobs:
npx playwright test --reporter=list
env:
OPENIDM_URL: http://localhost:8080
- name: UI Smoke Tests with /myidm context path (Playwright)
if: runner.os == 'Linux'
run: |
openidm/shutdown.sh || true
JAVA_OPTS="-Dopenidm.context.path=/myidm" openidm/startup.sh &
timeout 3m bash -c 'until grep -q "OpenIDM ready" openidm/logs/openidm0.log.0 ; do sleep 5; done' || cat openidm/logs/openidm0.log.0
cd e2e
npx playwright test --reporter=list
env:
OPENIDM_URL: http://localhost:8080
OPENIDM_CONTEXT_PATH: /myidm
- name: Test on Windows
if: runner.os == 'Windows'
run: |
Expand Down
5 changes: 3 additions & 2 deletions e2e/ui-smoke-test.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { test, expect } from "@playwright/test";
const BASE_URL = process.env.OPENIDM_URL || "http://localhost:8080";
const ADMIN_USER = process.env.OPENIDM_ADMIN_USER || "openidm-admin";
const ADMIN_PASS = process.env.OPENIDM_ADMIN_PASS || "openidm-admin";
const CONTEXT_PATH = process.env.OPENIDM_CONTEXT_PATH || "/openidm";

/** Log in to the Admin UI and wait for the navigation bar to appear. */
async function loginToAdmin(page) {
Expand Down Expand Up @@ -119,7 +120,7 @@ test.describe("OpenIDM UI Smoke Tests", () => {
});

test("REST API ping is accessible", async ({ request }) => {
const response = await request.get(`${BASE_URL}/openidm/info/ping`, {
const response = await request.get(`${BASE_URL}${CONTEXT_PATH}/info/ping`, {
headers: {
"X-OpenIDM-Username": ADMIN_USER,
"X-OpenIDM-Password": ADMIN_PASS,
Expand All @@ -131,7 +132,7 @@ test.describe("OpenIDM UI Smoke Tests", () => {
});

test("REST API config endpoint is accessible", async ({ request }) => {
const response = await request.get(`${BASE_URL}/openidm/config/ui/configuration`, {
const response = await request.get(`${BASE_URL}${CONTEXT_PATH}/config/ui/configuration`, {
headers: {
"X-OpenIDM-Username": ADMIN_USER,
"X-OpenIDM-Password": ADMIN_PASS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
*/
package org.forgerock.openidm.ui.internal.service;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
Expand Down Expand Up @@ -228,6 +230,8 @@ private void handle(HttpServletRequest req, HttpServletResponse res, URL url, St

if (!resourceModified(lastModified, req.getDateHeader("If-Modified-Since"))) {
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
} else if (resName.equals("/index.html")) {
copyIndexHtml(url, res);
} else {
copyResource(url, res);
}
Expand Down Expand Up @@ -277,6 +281,37 @@ private boolean resourceModified(long resTimestamp, long modSince) {
return resTimestamp == 0 || modSince == -1 || resTimestamp > modSince;
}

private void copyIndexHtml(URL url, HttpServletResponse res)
throws IOException {
String contextPath = IdentityServer.getInstance().getProperty("openidm.context.path", "/openidm");
if (contextPath.startsWith("/")) {
contextPath = contextPath.substring(1);
}
// Sanitize to prevent injection: allow only alphanumeric, hyphens and dots
contextPath = contextPath.replaceAll("[^a-zA-Z0-9\\-.]", "");

InputStream is = null;
try {
is = url.openStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n;
while ((n = is.read(buf, 0, buf.length)) >= 0) {
baos.write(buf, 0, n);
}
String html = baos.toString(StandardCharsets.UTF_8);
String injection = "<script>window.__openidm_context = \"" + contextPath + "\";</script>";
html = html.replaceFirst("</head>", injection + "</head>");
byte[] htmlBytes = html.getBytes(StandardCharsets.UTF_8);
res.setContentLength(htmlBytes.length);
res.getOutputStream().write(htmlBytes);
} finally {
if (is != null) {
is.close();
}
}
}

private void copyResource(URL url, HttpServletResponse res)
throws IOException {
OutputStream os = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function($, constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/audit/");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/audit/");

obj.availableHandlers = function() {
return obj.serviceCall({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ define([
"org/forgerock/commons/ui/common/main/EventManager"
], function($, _, constants, AbstractDelegate, eventManager) {

var obj = new AbstractDelegate(constants.host + "/openidm/system");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/system");

obj.connectorDelegateCache = {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function(constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/endpoint/oauthproxy");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/endpoint/oauthproxy");

obj.getToken = function(id, authCode, redirectUri, tokenUrl, connectorLocation) {
var googleDetails = "grant_type=authorization_code&code=" +authCode +"&client_id=" +id +"&redirect_uri=" +redirectUri,
Expand Down Expand Up @@ -48,7 +48,7 @@ define([
obj.externalRestRequest = (url, method, body, headers) => {
method = method || "GET";
return obj.serviceCall({
serviceUrl: constants.host + "/openidm/external/rest",
serviceUrl: constants.host + "/" + constants.context + "/external/rest",
url: "?_action=call",
type: "POST",
data: JSON.stringify({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function($, _, constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/maintenance");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/maintenance");

obj.getStatus = function () {
return obj.serviceCall({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ define([
"org/forgerock/commons/ui/common/main/Router"
], function($, _, constants, AbstractDelegate, configuration, eventManager, spinner, router) {

var obj = new AbstractDelegate(constants.host + "/openidm/recon");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/recon");

obj.waitForAll = function (reconIds, suppressSpinner, progressCallback, delayTime) {
var resultPromise = $.Deferred(),
Expand Down Expand Up @@ -149,7 +149,7 @@ define([
obj.stopRecon = function (id, suppressSpinner) {
return obj.serviceCall({
"suppressSpinner": suppressSpinner,
"serviceUrl": "/openidm/recon/" + id,
"serviceUrl": "/" + constants.context + "/recon/" + id,
"url": "?_action=cancel",
"type": "POST"
});
Expand All @@ -163,7 +163,7 @@ define([
getTargetObj = _.bind(function(link){
return this.serviceCall({
"type": "GET",
"serviceUrl": "/openidm/" + link.targetObjectId,
"serviceUrl": "/" + constants.context + "/" + link.targetObjectId,
"url": ""
}).then(function(targetObject){
newLinks.push({ sourceObjectId: link.sourceObjectId , targetObject: targetObject });
Expand All @@ -181,7 +181,7 @@ define([
} else {
this.serviceCall({
"type": "GET",
"serviceUrl": "/openidm/audit/recon",
"serviceUrl": "/" + constants.context + "/audit/recon",
"url": "?_queryFilter=" + encodeURIComponent(queryFilter)
}).then(function(qry){
if(qry.result.length){
Expand All @@ -205,7 +205,7 @@ define([
var queryFilter = 'reconId eq "' + reconId + '" and ' + objectIdType + ' eq "' + objectId + '"';
return obj.serviceCall({
"type": "GET",
"serviceUrl": "/openidm/audit/recon",
"serviceUrl": "/" + constants.context + "/audit/recon",
"url": "?_queryFilter=" + encodeURIComponent(queryFilter)
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function(_, $, constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/scheduler/job");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/scheduler/job");

obj.availableSchedules = function() {
return obj.serviceCall({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function(_, constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/script");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/script");

obj.evalScript = function(script, additionalGlobals) {
var scriptDetails = _.cloneDeep(script);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function($, constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/security");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/security");

obj.getPublicKeyCert = function (storeType, alias) {
var promise = $.Deferred();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ define([
"org/forgerock/openidm/ui/common/delegates/ConfigDelegate"
], function($, _, constants, AbstractDelegate, configuration, eventManager, configDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/sync");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/sync");

obj.performAction = function (reconId, mapping, action, sourceId, targetId, linkType) {
var params = {
Expand Down Expand Up @@ -69,13 +69,13 @@ define([
} else {

return obj.serviceCall({
"serviceUrl": constants.host + "/openidm/repo/link",
"serviceUrl": constants.host + "/" + constants.context + "/repo/link",
"url": "?_queryId=links-for-" + ordinal + "&linkType=" + linkType + "&" + ordinal + "=" + encodeURIComponent(id)
}).then(function (qry) {
var i, deletePromises = [];
for (i=0;i<qry.result.length;i++) {
deletePromises.push(obj.serviceCall({
"serviceUrl": constants.host + "/openidm/repo/link/",
"serviceUrl": constants.host + "/" + constants.context + "/repo/link/",
"url" : qry.result[i]._id,
"type": "DELETE",
"headers": {
Expand Down Expand Up @@ -160,7 +160,7 @@ define([
obj.mappingDetails = function(mapping){
var promise = $.Deferred(),
url = "",
serviceUrl = "/openidm/endpoint/mappingDetails",
serviceUrl = "/" + constants.context + "/endpoint/mappingDetails",
doServiceCall = function(){
return obj.serviceCall({
"type": "GET",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractDelegate"
], function(constants, AbstractDelegate) {

var obj = new AbstractDelegate(constants.host + "/openidm/workflow/processdefinition");
var obj = new AbstractDelegate(constants.host + "/" + constants.context + "/workflow/processdefinition");

obj.availableWorkflows = function() {
var errorHandlers = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractCollection",
"org/forgerock/commons/ui/common/main/ServiceInvoker",
"org/forgerock/commons/ui/common/components/Messages",
"org/forgerock/commons/ui/common/util/Constants",
"backgrid-paginator",
"backgrid-selectall"
], function($, _,
Expand All @@ -47,7 +48,8 @@ define([
BackgridUtils,
AbstractCollection,
ServiceInvoker,
Messages) {
Messages,
Constants) {

var DataAssociationManagementView = MappingAdminAbstractView.extend({
template: "templates/admin/mapping/association/DataAssociationManagementTemplate.html",
Expand Down Expand Up @@ -288,7 +290,7 @@ define([
grid_id = "#analysisGrid",
pager_id = grid_id + '-paginator',
ReconCollection = AbstractCollection.extend({
url: "/openidm/endpoint/reconResults",
url: "/" + Constants.context + "/endpoint/reconResults",
queryParams: {
_queryId: "reconResults",
source: this.mapping.source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ define([
concatPromise(() => {
return resourceDelegate.serviceCall({
"type": "POST",
"serviceUrl": "/openidm/repo/links",
"serviceUrl": "/" + constants.context + "/repo/links",
"url": "?_action=command&commandId=delete-mapping-links&mapping=" + mappingName
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function ($, _,
if ($(e.currentTarget).attr("disabled") !== "disabled") {

ResourceDelegate.serviceCall({
serviceUrl: "/openidm/managed/user",
serviceUrl: "/" + Constants.context + "/managed/user",
url: "/" + this.objectId + "?_action=resetPassword",
type: "POST",
success: (e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ define([

this.parentRender(_.bind(function() {
var processGrid,
ProcessModel = AbstractModel.extend({ "url": "/openidm/workflow/processinstance" }),
ProcessModel = AbstractModel.extend({ "url": "/" + constants.context + "/workflow/processinstance" }),
Process = AbstractCollection.extend({ model: ProcessModel });

this.model.processes = new Process();
Expand All @@ -69,7 +69,7 @@ define([
});
});

this.model.processes.url = "/openidm/workflow/processinstance?_queryId=filtered-query";
this.model.processes.url = "/" + constants.context + "/workflow/processinstance?_queryId=filtered-query";
this.model.processes.state.pageSize = null;
this.model.processes.state.sortKey = "-startTime";

Expand Down Expand Up @@ -228,9 +228,9 @@ define([
}

if(filterString.length > 0) {
this.model.processes.url = "/openidm/workflow/processinstance?" + filterString;
this.model.processes.url = "/" + constants.context + "/workflow/processinstance?" + filterString;
} else {
this.model.processes.url = "/openidm/workflow/processinstance?_queryId=query-all-ids";
this.model.processes.url = "/" + constants.context + "/workflow/processinstance?_queryId=query-all-ids";
}

this.model.processes.getFirstPage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ define([
"org/forgerock/commons/ui/common/main/AbstractModel",
"org/forgerock/openidm/ui/admin/util/WorkflowUtils"
], function(_, AbstractView, eventManager, constants, UIUtils, AbstractModel, WorkflowUtils) {
var ProcessModel = AbstractModel.extend({ url: "/openidm/workflow/processdefinition" }),
var ProcessModel = AbstractModel.extend({ url: "/" + constants.context + "/workflow/processdefinition" }),
ProcessDefinitionView = AbstractView.extend({
template: "templates/admin/workflow/ProcessDefinitionViewTemplate.html",

Expand All @@ -39,7 +39,7 @@ define([

this.data.processDefinition = this.model.toJSON();

this.data.diagramUrl = "/openidm/workflow/processdefinition/" + this.model.id + "?_fields=/diagram&_mimeType=image/png";
this.data.diagramUrl = "/" + constants.context + "/workflow/processdefinition/" + this.model.id + "?_fields=/diagram&_mimeType=image/png";

this.parentRender(_.bind(function(){

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ define([
"org/forgerock/commons/ui/common/main/AbstractModel",
"org/forgerock/commons/ui/common/main/AbstractCollection",
"backgrid",
"org/forgerock/openidm/ui/admin/util/BackgridUtils"
"org/forgerock/openidm/ui/admin/util/BackgridUtils",
"org/forgerock/commons/ui/common/util/Constants"
], function($, _,
AdminAbstractView,
AbstractModel,
AbstractCollection,
Backgrid,
BackgridUtils) {
BackgridUtils,
Constants) {
var ProcessDefinitionsView = AdminAbstractView.extend({
template: "templates/admin/workflow/ProcessDefinitionsViewTemplate.html",
events: {
Expand All @@ -40,11 +42,11 @@ define([
this.parentRender(_.bind(function(){
this.parentRender(_.bind(function() {
var processDefinitionGrid,
ProcessDefinitionModel = AbstractModel.extend({ "url": "/openidm/workflow/processdefinition" }),
ProcessDefinitionModel = AbstractModel.extend({ "url": "/" + Constants.context + "/workflow/processdefinition" }),
Process = AbstractCollection.extend({ model: ProcessDefinitionModel });

this.model.processes = new Process();
this.model.processes.url = "/openidm/workflow/processdefinition?_queryId=filtered-query";
this.model.processes.url = "/" + Constants.context + "/workflow/processdefinition?_queryId=filtered-query";
this.model.processes.state.pageSize = null;

processDefinitionGrid = new Backgrid.Grid({
Expand Down
Loading
Loading