DocSpace-client/common/ASC.SsoAuth/app/utils/converter.js

287 lines
8.8 KiB
JavaScript

/*
*
* (c) Copyright Ascensio System Limited 2010-2021
*
* Licensed 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.
*
*/
"use strict";
const config = require("../../config").get();
const saml = require("samlify");
const validator = require("@authenio/samlify-node-xmllint");
const urn = require("samlify/build/src/urn");
const _ = require("lodash");
const fs = require("fs");
const path = require("path");
const minifyXML = require("minify-xml").minify;
const logger = require("../log.js");
saml.setSchemaValidator(validator);
const ServiceProvider = saml.ServiceProvider;
const IdentityProvider = saml.IdentityProvider;
const templDir = path.join(process.cwd(),"../../common/ASC.SsoAuth", "/app/templates/");
module.exports = function () {
function removeCertHead(cert) {
var newCert = cert;
if (cert && cert[0] === "-") {
newCert = cert.replace(/-----.*-----/g, "");
}
return newCert;
}
function loadTemplate(conf, templName) {
try {
const tmplPath = path.join(templDir, `${templName}.xml`);
const template = minifyXML(
fs.readFileSync(tmplPath, { encoding: "utf-8" })
);
conf[`${templName}`] = {
context: template,
};
} catch (e) {
logger.error(`loadTemplate ${e.message}`);
}
}
return {
toIdp: function (ssoConfig) {
if (!ssoConfig && typeof ssoConfig !== "string") return undefined;
const idpSetting = {
entityID: ssoConfig.IdpSettings.EntityId,
nameIDFormat: [ssoConfig.IdpSettings.NameIdFormat],
requestSignatureAlgorithm:
ssoConfig.IdpCertificateAdvanced.VerifyAlgorithm,
dataEncryptionAlgorithm:
ssoConfig.IdpCertificateAdvanced.DecryptAlgorithm,
singleSignOnService: [
{
Binding: ssoConfig.IdpSettings.SsoBinding,
Location: ssoConfig.IdpSettings.SsoUrl,
},
],
singleLogoutService: [
{
Binding: ssoConfig.IdpSettings.SloBinding,
Location: ssoConfig.IdpSettings.SloUrl,
},
],
wantAuthnRequestsSigned:
ssoConfig.SpCertificateAdvanced.SignAuthRequests,
wantLogoutResponseSigned:
ssoConfig.SpCertificateAdvanced.SignLogoutResponses,
wantLogoutRequestSigned:
ssoConfig.SpCertificateAdvanced.SignLogoutRequests,
isAssertionEncrypted: ssoConfig.SpCertificateAdvanced.EncryptAssertions,
};
if (
Array.isArray(ssoConfig.IdpCertificates) &&
ssoConfig.IdpCertificates.length > 0
) {
idpSetting.signingCert = removeCertHead(
_.result(
_.find(ssoConfig.IdpCertificates, function (obj) {
return (
obj.Action === "verification" ||
obj.Action === "verification and decrypt"
);
}),
"Crt"
)
);
idpSetting.encryptCert = removeCertHead(
_.result(
_.find(ssoConfig.IdpCertificates, function (obj) {
return (
obj.Action === "decrypt" ||
obj.Action === "verification and decrypt"
);
}),
"Crt"
)
);
}
const idp = new IdentityProvider(idpSetting);
return idp;
},
toSp: function (ssoConfig, baseUrl) {
if (!ssoConfig && typeof ssoConfig !== "string")
throw "Invalid ssoConfig";
const metaUrl = baseUrl + "/sso" + config.routes.metadata,
acsUrl = baseUrl + "/sso" + config.routes.login_callback,
sloUrl = baseUrl + "/sso" + config.routes.logout_callback;
const spSetting = {
entityID: metaUrl,
nameIDFormat: [ssoConfig.IdpSettings.NameIdFormat],
requestSignatureAlgorithm:
ssoConfig.SpCertificateAdvanced.SigningAlgorithm,
dataEncryptionAlgorithm:
ssoConfig.SpCertificateAdvanced.EncryptAlgorithm,
assertionConsumerService: [
{
Binding: urn.namespace.binding.post,
Location: acsUrl,
},
{
Binding: urn.namespace.binding.redirect,
Location: acsUrl,
},
],
singleLogoutService: [
{
Binding: urn.namespace.binding.post,
Location: sloUrl,
},
{
Binding: urn.namespace.binding.redirect,
Location: sloUrl,
},
],
/*requestedAttributes: [
{
FriendlyName: "mail",
Name: "urn:oid:0.9.2342.19200300.100.1.3",
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
},
{
FriendlyName: "givenName",
Name: "urn:oid:2.5.4.42",
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
},
{
FriendlyName: "sn",
Name: "urn:oid:2.5.4.4",
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
},
{
FriendlyName: "mobile",
Name: "urn:oid:0.9.2342.19200300.100.1.41",
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
},
{
FriendlyName: "title",
Name: "urn:oid:2.5.4.12",
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
},
{
FriendlyName: "l",
Name: "urn:oid:2.5.4.7",
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
}
],*/
authnRequestsSigned: ssoConfig.SpCertificateAdvanced.SignAuthRequests,
wantAssertionsSigned:
ssoConfig.IdpCertificateAdvanced.VerifyAuthResponsesSign,
wantLogoutResponseSigned:
ssoConfig.IdpCertificateAdvanced.VerifyLogoutResponsesSign,
wantLogoutRequestSigned:
ssoConfig.IdpCertificateAdvanced.VerifyLogoutRequestsSign,
elementsOrder: [
"KeyDescriptor",
"SingleLogoutService",
"NameIDFormat",
"AssertionConsumerService",
"AttributeConsumingService",
],
//clockDrifts: [-60000, 60000],
};
if (
Array.isArray(ssoConfig.SpCertificates) &&
ssoConfig.SpCertificates.length > 0
) {
spSetting.privateKey = _.result(
_.find(ssoConfig.SpCertificates, function (obj) {
return (
obj.Action === "signing" || obj.Action === "signing and encrypt"
);
}),
"Key"
);
spSetting.privateKeyPass = "";
spSetting.encPrivateKey = _.result(
_.find(ssoConfig.SpCertificates, function (obj) {
return (
obj.Action === "encrypt" || obj.Action === "signing and encrypt"
);
}),
"Key"
);
spSetting.encPrivateKeyPass = "";
spSetting.signingCert = _.result(
_.find(ssoConfig.SpCertificates, function (obj) {
return (
obj.Action === "signing" || obj.Action === "signing and encrypt"
);
}),
"Crt"
);
spSetting.encryptCert = _.result(
_.find(ssoConfig.SpCertificates, function (obj) {
return (
obj.Action === "encrypt" || obj.Action === "signing and encrypt"
);
}),
"Crt"
);
// must have if assertion signature fails validation
spSetting.transformationAlgorithms = [
"http://www.w3.org/2000/09/xmldsig#enveloped-signature",
"http://www.w3.org/2001/10/xml-exc-c14n#",
];
}
loadTemplate(spSetting, "loginRequestTemplate");
loadTemplate(spSetting, "logoutRequestTemplate");
loadTemplate(spSetting, "logoutResponseTemplate");
//if (config.app.organization) {
// spSetting.organization = config.app.organization;
//}
//if (config.app.contact) {
// spSetting.contact = config.app.contact;
//}
const sp = new ServiceProvider(spSetting);
return sp;
},
};
};