policy.js revision f8eb547a5996303c92e9482cf659642871c7252c
286N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 286N/A * Copyright (c) 2012 ForgeRock AS. All Rights Reserved 286N/A * The contents of this file are subject to the terms 286N/A * of the Common Development and Distribution License 286N/A * (the License). You may not use this file except in 286N/A * compliance with the License. 286N/A * You can obtain a copy of the License at 286N/A * See the License for the specific language governing 286N/A * permission and limitations under the License. 286N/A * When distributing Covered Code, include this CDDL 286N/A * Header Notice in each file and include the License file 286N/A * If applicable, add the following below the CDDL Header, 286N/A * with the fields enclosed by brackets [] replaced by 286N/A * your own identifying information: 286N/A * "Portions Copyrighted [year] [name of copyright owner]" 286N/A {
"policyId" :
"required",
286N/A "policyExec" :
"required",
286N/A "clientValidation":
true,
286N/A "policyRequirements" : [
"REQUIRED"]
286N/A {
"policyId" :
"not-empty",
286N/A "policyExec" :
"notEmpty",
286N/A "clientValidation":
true,
286N/A "policyRequirements" : [
"REQUIRED"]
286N/A "policyId" :
"max-attempts-triggers-lock-cooldown",
286N/A "policyExec" :
"maxAttemptsTriggersLockCooldown",
286N/A "policyRequirements" : [
"NO_MORE_THAN_X_ATTEMPTS_WITHIN_Y_MINUTES"]
286N/A {
"policyId" :
"unique",
286N/A "policyExec" :
"unique",
286N/A "policyRequirements" : [
"UNIQUE"]
286N/A {
"policyId" :
"no-internal-user-conflict",
286N/A "policyExec" :
"noInternalUserConflict",
286N/A "policyRequirements" : [
"UNIQUE"]
286N/A "policyId" :
"valid-date",
286N/A "policyExec" :
"validDateWhenPresent",
286N/A "clientValidation":
true,
286N/A "policyRequirements": [
"VALID_DATE"]
286N/A "policyId" :
"valid-email-address-format",
286N/A "policyExec" :
"validEmailAddressFormatWhenPresent",
286N/A "clientValidation":
true,
286N/A "policyRequirements": [
"VALID_EMAIL_ADDRESS_FORMAT"]
286N/A "policyId" :
"valid-name-format",
286N/A "policyExec" :
"validNameFormatWhenPresent",
286N/A "clientValidation":
true,
286N/A "policyRequirements": [
"VALID_NAME_FORMAT"]
286N/A "policyId" :
"valid-phone-format",
286N/A "policyExec" :
"validPhoneFormatWhenPresent",
286N/A "clientValidation":
true,
286N/A "policyRequirements": [
"VALID_PHONE_FORMAT"]
286N/A {
"policyId" :
"at-least-X-capitals",
286N/A "clientValidation":
true,
286N/A "policyExec" :
"atLeastXCapitalLettersWhenPresent",
286N/A "policyRequirements" : [
"AT_LEAST_X_CAPITAL_LETTERS"]
286N/A {
"policyId" :
"at-least-X-numbers",
286N/A "clientValidation":
true,
286N/A "policyExec" :
"atLeastXNumbersWhenPresent",
286N/A "policyRequirements" : [
"AT_LEAST_X_NUMBERS"]
286N/A {
"policyId" :
"minimum-length",
286N/A "clientValidation":
true,
286N/A "policyExec" :
"minLengthWhenPresent",
286N/A "policyRequirements" : [
"MIN_LENGTH"]
286N/A {
"policyId" :
"cannot-contain-others",
286N/A "clientValidation":
true,
286N/A "policyExec" :
"cannotContainOthers",
286N/A "policyRequirements" : [
"CANNOT_CONTAIN_OTHERS"]
286N/A "policyId" :
"required-if-configured",
286N/A "policyExec":
"requiredIfConfigured",
286N/A "policyRequirements" : [
"REQUIRED"]
286N/A {
"policyId" :
"re-auth-required",
286N/A "policyExec" :
"reauthRequired",
286N/A "policyRequirements" : [
"REAUTH_REQUIRED"]
286N/A return [ {
"policyRequirement" :
"REQUIRED" } ];
286N/A return [ {
"policyRequirement":
"REQUIRED"}];
"_queryId":
"credential-internaluser-query",
return [{
"policyRequirement":
"UNIQUE"}];
"_queryId":
"get-by-field-value",
return [{
"policyRequirement":
"UNIQUE"}];
return [ {
"policyRequirement":
"VALID_DATE"}];
return [ {
"policyRequirement":
"VALID_PHONE_FORMAT"}];
var namePattern = /^([A-
Za'-\u0105\u0107\u0119\u0142\u00F3\u015B\u017C\u017A\u0104\u0106\u0118\u0141\u00D3\u015A\u017B\u0179\u00C0\u00C8\u00CC\u00D2\u00D9\u00E0\u00E8\u00EC\u00F2\u00F9\u00C1\u00C9\u00CD\u00D3\u00DA\u00DD\u00E1\u00E9\u00ED\u00F3\u00FA\u00FD\u00C2\u00CA\u00CE\u00D4\u00DB\u00E2\u00EA\u00EE\u00F4\u00FB\u00C3\u00D1\u00D5\u00E3\u00F1\u00F5\u00C4\u00CB\u00CF\u00D6\u00DC\u0178\u00E4\u00EB\u00EF\u00F6\u00FC\u0178\u00A1\u00BF\u00E7\u00C7\u0152\u0153\u00DF\u00D8\u00F8\u00C5\u00E5\u00C6\u00E6\u00DE\u00FE\u00D0\u00F0\-\s])+$/; if (typeof(value) === "string" && value.length && !namePattern.test(value)) return [ {"policyRequirement": "VALID_NAME_FORMAT"}]; function minLengthWhenPresent(fullObject, value, params, property) { var minLength = params.minLength; if (typeof(value) === "string" && value.length && value.length < minLength) { return [ { "policyRequirement" : "MIN_LENGTH", "params" : {"minLength":minLength} } ]; function atLeastXCapitalLettersWhenPresent(fullObject, value, params, property) { if (typeof value === "string" && value.length && (value.match(reg) === null || value.match(reg).length < params.numCaps)) { return [ { "policyRequirement" : "AT_LEAST_X_CAPITAL_LETTERS", "params" : {"numCaps": params.numCaps} } ]; function atLeastXNumbersWhenPresent(fullObject, value, params, property) { if (typeof value === "string" && value.length && (value.match(reg) === null || value.match(reg).length < params.numNums)) { return [ { "policyRequirement" : "AT_LEAST_X_NUMBERS", "params" : {"numNums": params.numNums} } ]; function validEmailAddressFormatWhenPresent(fullObject, value, params, property) { var emailPattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; if (typeof value === "string" && value.length && !emailPattern.test(value)) return [ {"policyRequirement": "VALID_EMAIL_ADDRESS_FORMAT"}]; function cannotContainOthers(fullObject, value, params, property) { var fieldArray = params.disallowedFields.split(","), if (typeof(openidm) !== "undefined" && typeof(request) !== "undefined" && request.id && !request.id.match('/$
')) { fullObject_server = openidm.read(request.id) if (value && typeof(value) === "string" && value.length) { for (var i = 0; i < fieldArray.length; i++) { if (typeof(fullObject[fieldArray[i]]) === "undefined" && typeof(fullObject_server[fieldArray[i]]) !== "undefined") { fullObject[fieldArray[i]] = fullObject_server[fieldArray[i]]; if (typeof(fullObject[fieldArray[i]]) === "string" && value.match(fullObject[fieldArray[i]])) return [{"policyRequirement": "CANNOT_CONTAIN_OTHERS", params: {"disallowedFields": fieldArray[i]}}]; function requiredIfConfigured(fullObject, value, params, property) { var currentValue = openidm.read("config/" + params.configBase), baseKeyArray = params.baseKey.split("."), security = getHighestRequest(request).security; roles = security["openidm-roles"]; if (params && params.exceptRoles) { for (i = 0; i < params.exceptRoles.length; i++) { role = params.exceptRoles[i]; for (j = 0; j < roles.length; j++) { for (var i in baseKeyArray) currentValue = currentValue[baseKeyArray[i]]; if (currentValue && (!value || !value.length)) return [ {"policyRequirement": "REQUIRED"}]; function reauthRequired(fullObject, value, params, propName) { var exceptRoles, highestRequest, type, role, roles, i, j; highestRequest = getHighestRequest(request); type = highestRequest.type; if (highestRequest.security) { roles = highestRequest.security["openidm-roles"]; if (params && params.exceptRoles) { exceptRoles = params.exceptRoles; for (i = 0; i < exceptRoles.length; i++) { for (j = 0; j < roles.length; j++) { "_action": "reauthenticate" var response = openidm.action("authentication", actionParams); return [ { "policyRequirement" : "REAUTH_REQUIRED" } ]; // End of policy enforcement functions // Internal policy code below function getHighestRequest(request) { var currentRequest = request; while (currentRequest.parent && typeof(currentRequest.security) === "undefined") { currentRequest = currentRequest.parent; function getPolicy(policyId) { for (var i = 0; i < policyConfig.policies.length; i++) { if (policyConfig.policies[i].policyId == policyId) { return policyConfig.policies[i]; function getPropertyValue(requestObject, propName) { var propAddress = propName.split("/"); var tmpObject = requestObject; for (var i = 0; i < propAddress.length; i++) { tmpObject = tmpObject[propAddress[i]]; if (tmpObject === undefined || tmpObject === null) { function getPropertyConfig(resource, propName) { for (var i = 0; i < props.length; i++) { if (prop.name == propName) { function getResource(resources, resourceName) { for (var i = 0; i < resources.length; i++) { var resource = resources[i]; if (resourceMatches(resource.resource, resourceName)) { function resourceMatches(resource1, resource2) { rsrc1 = resource1.split("/"); rsrc2 = resource2.split("/"); if (rsrc1.length == rsrc2.length) { for (var i = 0; i < rsrc1.length; i++) { if (rsrc1[i] != rsrc2[i] && function getResourceWithPolicyRequirements(resource) { // Loop through the properties for this resource for (var i = 0; i < compProps.length; i++) { var propPolicyReqs = new Array(); // loop through the policies of each property for (var j = 0; j < prop.policies.length; j++) { var policy = getPolicy(prop.policies[j].policyId); // Check if client validation is enabled, if so add source if ((policy.clientValidation !== undefined) && policy.clientValidation) { prop.policies[j].policyFunction = eval(policy.policyExec).toString(); prop.policies[j].policyRequirements = policy.policyRequirements; reqs = policy.policyRequirements; // loop through the requirements for each policy for (var x = 0; x < reqs.length; x++) { // Add the requirements array to the property object // Return all property configs for this resource // update old policy with new config // Get the policy configuration for the specified resource // Update the policy configuration with any resource specific }
else if (
method ==
"action") {
throw "No resource specified";
// There is no configured policies for this resource (nothing to verify) // Perform the validation if (
action ==
"validateObject") {
}
else if (
action ==
"validateProperty") {
throw "Unsupported action: " +
action;
// Set the result to true if no failedPolicyRequirements (failures), false otherwise // Set the return failedPolicyRequirements throw "Unsupported method: " +
method;
//Load additional policy scripts if configured