From ce6489c4eccd1b866c29fa07c741cb8a6bd2c7c0 Mon Sep 17 00:00:00 2001 From: Shad Vider Date: Wed, 21 Apr 2021 10:48:10 -0700 Subject: [PATCH 01/18] adding pac4j header authentication - very much a WIP --- pac4j-module/build.gradle | 1 + .../net/unicon/shibui/pac4j/HeaderClient.java | 77 +++++++++++++++++++ .../shibui/pac4j/Pac4jConfiguration.java | 24 ++++++ .../pac4j/Pac4jConfigurationProperties.java | 4 + 4 files changed, 106 insertions(+) create mode 100644 pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index 2d952a4c8..18eb7be38 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -26,6 +26,7 @@ dependencies { compileOnly project(':backend') compile "org.pac4j:spring-security-pac4j:4.0.0" + compile "org.pac4j:pac4j-http:4.0.0" compile "org.pac4j:pac4j-core:3.3.0" compile "org.pac4j:pac4j-saml:3.3.0", { // opensaml libraries are provided diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java new file mode 100644 index 000000000..95ed9e414 --- /dev/null +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java @@ -0,0 +1,77 @@ +package net.unicon.shibui.pac4j; + +import org.pac4j.core.client.DirectClient; +import org.pac4j.core.credentials.authenticator.Authenticator; +import org.pac4j.core.profile.creator.ProfileCreator; +import org.pac4j.core.util.CommonHelper; +import org.pac4j.core.credentials.extractor.HeaderExtractor; + + +public abstract class HeaderClient extends DirectClient { + + private String headerName = ""; + + private String prefixHeader = ""; + + public HeaderClient() {} + + public HeaderClient(final String headerName, final Authenticator tokenAuthenticator) { + this.headerName = headerName; + defaultAuthenticator(tokenAuthenticator); + } + + public HeaderClient(final String headerName, final String prefixHeader, + final Authenticator tokenAuthenticator) { + this.headerName = headerName; + this.prefixHeader = prefixHeader; + defaultAuthenticator(tokenAuthenticator); + } + + public HeaderClient(final String headerName, final Authenticator tokenAuthenticator, + final ProfileCreator profileCreator) { + this.headerName = headerName; + defaultAuthenticator(tokenAuthenticator); + defaultProfileCreator(profileCreator); + } + + public HeaderClient(final String headerName, final String prefixHeader, + final Authenticator tokenAuthenticator, final ProfileCreator profileCreator) { + this.headerName = headerName; + this.prefixHeader = prefixHeader; + defaultAuthenticator(tokenAuthenticator); + defaultProfileCreator(profileCreator); + } + +// @Override +// protected void internalInit() { +// if (getCredentialsExtractor() == null) { +// CommonHelper.assertNotBlank("headerName", this.headerName); +// CommonHelper.assertNotNull("prefixHeader", this.prefixHeader); +// +// defaultCredentialsExtractor(new HeaderExtractor(this.headerName, this.prefixHeader)); +// } +// } + + public String getHeaderName() { + return headerName; + } + + public void setHeaderName(String headerName) { + this.headerName = headerName; + } + + public String getPrefixHeader() { + return prefixHeader; + } + + public void setPrefixHeader(String prefixHeader) { + this.prefixHeader = prefixHeader; + } + + @Override + public String toString() { + return CommonHelper.toNiceString(this.getClass(), "name", getName(), "headerName", this.headerName, + "prefixHeader", this.prefixHeader, "extractor", getCredentialsExtractor(), "authenticator", getAuthenticator(), + "profileCreator", getProfileCreator()); + } +} diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index d96e4b352..21ece558b 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -3,6 +3,8 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; +import org.pac4j.core.credentials.TokenCredentials; +import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.definition.CommonProfileDefinition; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.client.SAML2ClientConfiguration; @@ -47,4 +49,26 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigurationProper final Config config = new Config(clients); return config; } + + @Bean + public Config headerConfig() { + HeaderClient client = new HeaderClient("Authorization", "Basic ", (credentials, ctx) -> { + String token = ((TokenCredentials) credentials).getToken(); + // check the token and create a profile + if ("goodToken".equals(token)) { + CommonProfile profile = new CommonProfile(); + profile.setId("myId"); + // save in the credentials to be passed to the default AuthenticatorProfileCreator + credentials.setUserProfile(profile); + } + }) { + @Override + protected void clientInit() { + } + }; + + final Config config = new Config(client); + return config; + } + } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 47defac65..8103f7356 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -21,6 +21,7 @@ public class Pac4jConfigurationProperties { private String callbackUrl; private boolean wantAssertionsSigned = true; private SAML2ProfileMapping saml2ProfileMapping; + private boolean enableHeaderAuthentication = true; public static class SAML2ProfileMapping { private String username; @@ -148,4 +149,7 @@ public SAML2ProfileMapping getSaml2ProfileMapping() { public void setSaml2ProfileMapping(SAML2ProfileMapping saml2ProfileMapping) { this.saml2ProfileMapping = saml2ProfileMapping; } + + public boolean getEnableHeaderAuthentication() { return enableHeaderAuthentication; } + } From 51e7cef8c8e8b08407bcc6b3f3b01754e34c723e Mon Sep 17 00:00:00 2001 From: Shad Vider Date: Tue, 25 May 2021 17:34:53 -0700 Subject: [PATCH 02/18] adding pac4j header authentication --- .../net/unicon/shibui/pac4j/HeaderClient.java | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java deleted file mode 100644 index 95ed9e414..000000000 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/HeaderClient.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.unicon.shibui.pac4j; - -import org.pac4j.core.client.DirectClient; -import org.pac4j.core.credentials.authenticator.Authenticator; -import org.pac4j.core.profile.creator.ProfileCreator; -import org.pac4j.core.util.CommonHelper; -import org.pac4j.core.credentials.extractor.HeaderExtractor; - - -public abstract class HeaderClient extends DirectClient { - - private String headerName = ""; - - private String prefixHeader = ""; - - public HeaderClient() {} - - public HeaderClient(final String headerName, final Authenticator tokenAuthenticator) { - this.headerName = headerName; - defaultAuthenticator(tokenAuthenticator); - } - - public HeaderClient(final String headerName, final String prefixHeader, - final Authenticator tokenAuthenticator) { - this.headerName = headerName; - this.prefixHeader = prefixHeader; - defaultAuthenticator(tokenAuthenticator); - } - - public HeaderClient(final String headerName, final Authenticator tokenAuthenticator, - final ProfileCreator profileCreator) { - this.headerName = headerName; - defaultAuthenticator(tokenAuthenticator); - defaultProfileCreator(profileCreator); - } - - public HeaderClient(final String headerName, final String prefixHeader, - final Authenticator tokenAuthenticator, final ProfileCreator profileCreator) { - this.headerName = headerName; - this.prefixHeader = prefixHeader; - defaultAuthenticator(tokenAuthenticator); - defaultProfileCreator(profileCreator); - } - -// @Override -// protected void internalInit() { -// if (getCredentialsExtractor() == null) { -// CommonHelper.assertNotBlank("headerName", this.headerName); -// CommonHelper.assertNotNull("prefixHeader", this.prefixHeader); -// -// defaultCredentialsExtractor(new HeaderExtractor(this.headerName, this.prefixHeader)); -// } -// } - - public String getHeaderName() { - return headerName; - } - - public void setHeaderName(String headerName) { - this.headerName = headerName; - } - - public String getPrefixHeader() { - return prefixHeader; - } - - public void setPrefixHeader(String prefixHeader) { - this.prefixHeader = prefixHeader; - } - - @Override - public String toString() { - return CommonHelper.toNiceString(this.getClass(), "name", getName(), "headerName", this.headerName, - "prefixHeader", this.prefixHeader, "extractor", getCredentialsExtractor(), "authenticator", getAuthenticator(), - "profileCreator", getProfileCreator()); - } -} From 3dc330b19538445eba14c06a002f465f09ae3f09 Mon Sep 17 00:00:00 2001 From: Shad Vider Date: Tue, 25 May 2021 18:09:05 -0700 Subject: [PATCH 03/18] adding pac4j header authentication --- .../shibui/pac4j/Pac4jConfiguration.java | 73 +++-- .../pac4j/Pac4jConfigurationProperties.java | 19 +- .../net/unicon/shibui/pac4j/WebSecurity.java | 2 + ui/package-lock.json | 267 +++++++++--------- 4 files changed, 191 insertions(+), 170 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index 21ece558b..e4ac06a26 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -3,12 +3,17 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; +import org.pac4j.core.context.WebContext; +import org.pac4j.core.credentials.Credentials; import org.pac4j.core.credentials.TokenCredentials; +import org.pac4j.core.credentials.authenticator.Authenticator; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.definition.CommonProfileDefinition; +import org.pac4j.http.client.direct.ParameterClient; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.client.SAML2ClientConfiguration; import org.pac4j.saml.credentials.authenticator.SAML2Authenticator; +import org.pac4j.http.client.direct.HeaderClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -23,52 +28,42 @@ public SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator(UserRep @Bean public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties, final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { - final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); - saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); - saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); - saml2ClientConfiguration.setPrivateKeyPassword(pac4jConfigurationProperties.getPrivateKeyPassword()); - saml2ClientConfiguration.setIdentityProviderMetadataPath(pac4jConfigurationProperties.getIdentityProviderMetadataPath()); - saml2ClientConfiguration.setMaximumAuthenticationLifetime(pac4jConfigurationProperties.getMaximumAuthenticationLifetime()); - saml2ClientConfiguration.setServiceProviderEntityId(pac4jConfigurationProperties.getServiceProviderEntityId()); - saml2ClientConfiguration.setServiceProviderMetadataPath(pac4jConfigurationProperties.getServiceProviderMetadataPath()); - saml2ClientConfiguration.setForceServiceProviderMetadataGeneration(pac4jConfigurationProperties.isForceServiceProviderMetadataGeneration()); - saml2ClientConfiguration.setWantsAssertionsSigned(pac4jConfigurationProperties.isWantAssertionsSigned()); - saml2ClientConfiguration.setAttributeAsId(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()); + final Clients clients = new Clients(pac4jConfigurationProperties.getCallbackUrl()); - final SAML2Client saml2Client = new SAML2Client(saml2ClientConfiguration); - saml2Client.setName("Saml2Client"); - saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); + if(pac4jConfigurationProperties.getTypeOfAuth().equals("SAML2")) { //f + final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); + saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); + saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); + saml2ClientConfiguration.setPrivateKeyPassword(pac4jConfigurationProperties.getPrivateKeyPassword()); + saml2ClientConfiguration.setIdentityProviderMetadataPath(pac4jConfigurationProperties.getIdentityProviderMetadataPath()); + saml2ClientConfiguration.setMaximumAuthenticationLifetime(pac4jConfigurationProperties.getMaximumAuthenticationLifetime()); + saml2ClientConfiguration.setServiceProviderEntityId(pac4jConfigurationProperties.getServiceProviderEntityId()); + saml2ClientConfiguration.setServiceProviderMetadataPath(pac4jConfigurationProperties.getServiceProviderMetadataPath()); + saml2ClientConfiguration.setForceServiceProviderMetadataGeneration(pac4jConfigurationProperties.isForceServiceProviderMetadataGeneration()); + saml2ClientConfiguration.setWantsAssertionsSigned(pac4jConfigurationProperties.isWantAssertionsSigned()); + saml2ClientConfiguration.setAttributeAsId(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()); - SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2ClientConfiguration.getAttributeAsId(), saml2ClientConfiguration.getMappedAttributes()); - saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>(p -> new BetterSAML2Profile(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()))); - saml2Client.setAuthenticator(saml2Authenticator); + final SAML2Client saml2Client = new SAML2Client(saml2ClientConfiguration); + saml2Client.setName("Saml2Client"); + saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); + SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2ClientConfiguration.getAttributeAsId(), saml2ClientConfiguration.getMappedAttributes()); + saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>(p -> new BetterSAML2Profile(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()))); + saml2Client.setAuthenticator(saml2Authenticator); - final Clients clients = new Clients(pac4jConfigurationProperties.getCallbackUrl(), saml2Client); - - final Config config = new Config(clients); - return config; - } - - @Bean - public Config headerConfig() { - HeaderClient client = new HeaderClient("Authorization", "Basic ", (credentials, ctx) -> { - String token = ((TokenCredentials) credentials).getToken(); - // check the token and create a profile - if ("goodToken".equals(token)) { - CommonProfile profile = new CommonProfile(); - profile.setId("myId"); - // save in the credentials to be passed to the default AuthenticatorProfileCreator - credentials.setUserProfile(profile); - } - }) { + clients.setClients(saml2Client); + } + else if (pac4jConfigurationProperties.getTypeOfAuth().equals("HEADER")) { + HeaderClient headerClient = new HeaderClient(pac4jConfigurationProperties.getAuthenticationHeader(), new Authenticator() { @Override - protected void clientInit() { + public void validate(Credentials credentials, WebContext context) { + } - }; + }); + clients.setClients(headerClient); + } - final Config config = new Config(client); + final Config config = new Config(clients); return config; } - } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 8103f7356..55a94bb73 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -21,7 +21,8 @@ public class Pac4jConfigurationProperties { private String callbackUrl; private boolean wantAssertionsSigned = true; private SAML2ProfileMapping saml2ProfileMapping; - private boolean enableHeaderAuthentication = true; + private String typeOfAuth = "SAML2"; + private String authenticationHeader = "REMOTE_USER"; public static class SAML2ProfileMapping { private String username; @@ -150,6 +151,20 @@ public void setSaml2ProfileMapping(SAML2ProfileMapping saml2ProfileMapping) { this.saml2ProfileMapping = saml2ProfileMapping; } - public boolean getEnableHeaderAuthentication() { return enableHeaderAuthentication; } + public String getTypeOfAuth() { + return typeOfAuth; + } + + public void setTypeOfAuth(String typeOfAuth) { + this.typeOfAuth = typeOfAuth; + } + public String getAuthenticationHeader() { + return authenticationHeader; + } + + public void setAuthenticationHeader(String authenticationHeader) { + this.authenticationHeader = authenticationHeader; + } } + diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 907cc6963..fc3a7c081 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -83,10 +83,12 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository use @Override protected void configure(HttpSecurity http) throws Exception { final SecurityFilter securityFilter = new SecurityFilter(this.config, "Saml2Client"); + final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, "HeaderClient"); final CallbackFilter callbackFilter = new CallbackFilter(this.config); http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class) .addFilterBefore(securityFilter, BasicAuthenticationFilter.class) + .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) //xxx check on this .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); diff --git a/ui/package-lock.json b/ui/package-lock.json index 516c84556..f13e4df3b 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1323,6 +1323,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.10", @@ -1345,6 +1346,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1353,6 +1355,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1363,6 +1366,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1373,6 +1377,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1381,6 +1386,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1389,6 +1395,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -1398,12 +1405,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -1414,6 +1423,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -1430,6 +1440,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1440,6 +1451,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -1448,6 +1460,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -1455,12 +1468,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -1867,6 +1882,7 @@ "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, "requires": { "@babel/types": "^7.12.7" }, @@ -1875,6 +1891,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1887,6 +1904,7 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, "requires": { "@babel/types": "^7.12.5" }, @@ -1895,6 +1913,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1907,6 +1926,7 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.1", "@babel/helper-replace-supers": "^7.12.1", @@ -1923,6 +1943,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1931,6 +1952,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1941,6 +1963,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1951,6 +1974,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1959,6 +1983,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1967,6 +1992,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -1976,12 +2002,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -1992,6 +2020,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2008,6 +2037,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2018,6 +2048,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2025,12 +2056,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -2038,6 +2071,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, "requires": { "@babel/types": "^7.12.10" }, @@ -2046,6 +2080,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2088,6 +2123,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.12.7", "@babel/helper-optimise-call-expression": "^7.12.10", @@ -2099,6 +2135,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2107,6 +2144,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2117,6 +2155,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2127,6 +2166,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2135,6 +2175,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2143,6 +2184,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2152,12 +2194,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2168,6 +2212,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2184,6 +2229,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2194,6 +2240,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2201,12 +2248,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -2214,6 +2263,7 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, "requires": { "@babel/types": "^7.12.1" }, @@ -2222,6 +2272,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2277,7 +2328,8 @@ "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.12.11", @@ -2429,6 +2481,7 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "dev": true, "requires": { "@babel/template": "^7.10.4", "@babel/traverse": "^7.12.5", @@ -2439,6 +2492,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2447,6 +2501,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2457,6 +2512,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2467,6 +2523,7 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2475,6 +2532,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2483,6 +2541,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2492,12 +2551,14 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2508,6 +2569,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2524,6 +2586,7 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2534,6 +2597,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2541,12 +2605,14 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -3548,7 +3614,8 @@ "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true }, "@jsdevtools/coverage-istanbul-loader": { "version": "3.0.5", @@ -4533,6 +4600,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -4839,7 +4907,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -5139,6 +5208,7 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5533,6 +5603,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", + "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -5910,6 +5981,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, "requires": { "color-name": "^1.1.1" } @@ -5917,7 +5989,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "color-string": { "version": "1.5.4", @@ -6062,7 +6135,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.0", @@ -7901,7 +7975,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "eslint-scope": { "version": "4.0.3", @@ -8843,7 +8918,8 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, "get-caller-file": { "version": "2.0.5", @@ -8932,7 +9008,8 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "globby": { "version": "11.0.2", @@ -9078,7 +9155,8 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true }, "has-symbols": { "version": "1.0.0", @@ -9270,7 +9348,8 @@ "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, "http-cache-semantics": { "version": "4.1.0", @@ -10007,12 +10086,14 @@ "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true }, "istanbul-lib-instrument": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, "requires": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", @@ -10023,7 +10104,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -10031,6 +10113,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", @@ -10040,96 +10123,17 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { - "glob": "^7.1.3" + "has-flag": "^4.0.0" } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } } }, @@ -10137,6 +10141,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -10213,7 +10218,8 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.14.1", @@ -10277,6 +10283,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -10620,6 +10627,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", + "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^4.0.1", @@ -10633,6 +10641,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -10641,6 +10650,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -10650,28 +10660,17 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, - "karma-coverage-istanbul-reporter": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", - "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^3.0.2", - "minimatch": "^3.0.4" - } - }, "karma-jasmine": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz", @@ -10909,7 +10908,8 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true }, "lodash.get": { "version": "4.4.2", @@ -11042,6 +11042,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, "requires": { "semver": "^6.0.0" }, @@ -11049,7 +11050,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -11413,6 +11415,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -11420,7 +11423,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "minipass": { "version": "3.1.3", @@ -16092,7 +16096,8 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -16247,7 +16252,8 @@ "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true }, "semver-dsl": { "version": "1.0.1", @@ -16836,7 +16842,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "source-map-loader": { "version": "1.1.3", @@ -17520,6 +17527,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -17941,7 +17949,8 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true }, "to-object-path": { "version": "0.3.0", From 12faa7cf505b8ff3326e07ff9846750d15789cae Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 23 Jun 2021 12:10:20 -0700 Subject: [PATCH 04/18] SHIBUI-1774 Undoing package-lock.json changes --- ui/package-lock.json | 267 +++++++++++++++++++++---------------------- 1 file changed, 129 insertions(+), 138 deletions(-) diff --git a/ui/package-lock.json b/ui/package-lock.json index f13e4df3b..516c84556 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1323,7 +1323,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.10", @@ -1346,7 +1345,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1355,7 +1353,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1366,7 +1363,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1377,7 +1373,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1386,7 +1381,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1395,7 +1389,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -1405,14 +1398,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -1423,7 +1414,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -1440,7 +1430,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1451,7 +1440,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -1460,7 +1448,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -1468,14 +1455,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -1882,7 +1867,6 @@ "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "dev": true, "requires": { "@babel/types": "^7.12.7" }, @@ -1891,7 +1875,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1904,7 +1887,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, "requires": { "@babel/types": "^7.12.5" }, @@ -1913,7 +1895,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -1926,7 +1907,6 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.1", "@babel/helper-replace-supers": "^7.12.1", @@ -1943,7 +1923,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -1952,7 +1931,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -1963,7 +1941,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -1974,7 +1951,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -1983,7 +1959,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -1992,7 +1967,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2002,14 +1976,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2020,7 +1992,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2037,7 +2008,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2048,7 +2018,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -2056,14 +2025,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -2071,7 +2038,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, "requires": { "@babel/types": "^7.12.10" }, @@ -2080,7 +2046,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2123,7 +2088,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.12.7", "@babel/helper-optimise-call-expression": "^7.12.10", @@ -2135,7 +2099,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2144,7 +2107,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2155,7 +2117,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2166,7 +2127,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2175,7 +2135,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2184,7 +2143,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2194,14 +2152,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2212,7 +2168,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2229,7 +2184,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2240,7 +2194,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -2248,14 +2201,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -2263,7 +2214,6 @@ "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", - "dev": true, "requires": { "@babel/types": "^7.12.1" }, @@ -2272,7 +2222,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2328,8 +2277,7 @@ "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" }, "@babel/helper-validator-option": { "version": "7.12.11", @@ -2481,7 +2429,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", - "dev": true, "requires": { "@babel/template": "^7.10.4", "@babel/traverse": "^7.12.5", @@ -2492,7 +2439,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2501,7 +2447,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, "requires": { "@babel/types": "^7.12.11", "jsesc": "^2.5.1", @@ -2512,7 +2457,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.10", "@babel/template": "^7.12.7", @@ -2523,7 +2467,6 @@ "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, "requires": { "@babel/types": "^7.12.10" } @@ -2532,7 +2475,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, "requires": { "@babel/types": "^7.12.11" } @@ -2541,7 +2483,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -2551,14 +2492,12 @@ "@babel/parser": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.12.7", @@ -2569,7 +2508,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@babel/generator": "^7.12.11", @@ -2586,7 +2524,6 @@ "version": "7.12.12", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -2597,7 +2534,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -2605,14 +2541,12 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -3614,8 +3548,7 @@ "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" }, "@jsdevtools/coverage-istanbul-loader": { "version": "3.0.5", @@ -4600,7 +4533,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -4907,8 +4839,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", @@ -5208,7 +5139,6 @@ "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5603,7 +5533,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", - "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -5981,7 +5910,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, "requires": { "color-name": "^1.1.1" } @@ -5989,8 +5917,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.5.4", @@ -6135,8 +6062,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.0", @@ -7975,8 +7901,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint-scope": { "version": "4.0.3", @@ -8918,8 +8843,7 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", @@ -9008,8 +8932,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "globby": { "version": "11.0.2", @@ -9155,8 +9078,7 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" }, "has-symbols": { "version": "1.0.0", @@ -9348,8 +9270,7 @@ "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "http-cache-semantics": { "version": "4.1.0", @@ -10086,14 +10007,12 @@ "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" }, "istanbul-lib-instrument": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, "requires": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", @@ -10104,8 +10023,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -10113,7 +10031,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", @@ -10123,25 +10040,103 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "istanbul-reports": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -10218,8 +10213,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.14.1", @@ -10283,7 +10277,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dev": true, "requires": { "minimist": "^1.2.5" } @@ -10627,7 +10620,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz", "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==", - "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^4.0.1", @@ -10641,7 +10633,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -10650,7 +10641,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -10660,17 +10650,28 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, + "karma-coverage-istanbul-reporter": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", + "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^3.0.2", + "minimatch": "^3.0.4" + } + }, "karma-jasmine": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz", @@ -10908,8 +10909,7 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.get": { "version": "4.4.2", @@ -11042,7 +11042,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, "requires": { "semver": "^6.0.0" }, @@ -11050,8 +11049,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -11415,7 +11413,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -11423,8 +11420,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { "version": "3.1.3", @@ -16096,8 +16092,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "safe-regex": { "version": "1.1.0", @@ -16252,8 +16247,7 @@ "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" }, "semver-dsl": { "version": "1.0.1", @@ -16842,8 +16836,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-loader": { "version": "1.1.3", @@ -17527,7 +17520,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -17949,8 +17941,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", From c5da066e2c43fb1d94fbd3705c508c792dbfbf58 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 23 Jun 2021 14:15:49 -0700 Subject: [PATCH 05/18] SHIBUI-1774 minor cleanup --- .../shibui/pac4j/Pac4jConfiguration.java | 24 ++++++++++++------- .../pac4j/Pac4jConfigurationProperties.java | 4 +++- .../net/unicon/shibui/pac4j/WebSecurity.java | 4 ---- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index e4ac06a26..c885f0049 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -7,6 +7,7 @@ import org.pac4j.core.credentials.Credentials; import org.pac4j.core.credentials.TokenCredentials; import org.pac4j.core.credentials.authenticator.Authenticator; +import org.pac4j.core.exception.CredentialsException; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.definition.CommonProfileDefinition; import org.pac4j.http.client.direct.ParameterClient; @@ -27,11 +28,12 @@ public SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator(UserRep } @Bean - public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties, final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { + public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties, + final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { final Clients clients = new Clients(pac4jConfigurationProperties.getCallbackUrl()); - if(pac4jConfigurationProperties.getTypeOfAuth().equals("SAML2")) { //f + if (pac4jConfigurationProperties.getTypeOfAuth().equals("SAML2")) { final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); @@ -47,17 +49,23 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigurationProper final SAML2Client saml2Client = new SAML2Client(saml2ClientConfiguration); saml2Client.setName("Saml2Client"); saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); - SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2ClientConfiguration.getAttributeAsId(), saml2ClientConfiguration.getMappedAttributes()); - saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>(p -> new BetterSAML2Profile(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()))); + SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2ClientConfiguration.getAttributeAsId(), + saml2ClientConfiguration.getMappedAttributes()); + saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>( + p -> new BetterSAML2Profile(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()))); saml2Client.setAuthenticator(saml2Authenticator); clients.setClients(saml2Client); - } - else if (pac4jConfigurationProperties.getTypeOfAuth().equals("HEADER")) { - HeaderClient headerClient = new HeaderClient(pac4jConfigurationProperties.getAuthenticationHeader(), new Authenticator() { + } else if (pac4jConfigurationProperties.getTypeOfAuth().equals("HEADER")) { + HeaderClient headerClient = new HeaderClient(pac4jConfigurationProperties.getAuthenticationHeader(), new Authenticator() { @Override public void validate(Credentials credentials, WebContext context) { - + if (credentials instanceof TokenCredentials) { + TokenCredentials creds = (TokenCredentials) credentials; + String remoteUser = creds.getToken(); + } else { + throw new CredentialsException("Invalid Credentials object generated by HeaderClient"); + } } }); clients.setClients(headerClient); diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 55a94bb73..57e38d91b 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -10,6 +10,8 @@ @EnableConfigurationProperties @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") public class Pac4jConfigurationProperties { + final static String DEFAULT_AUTH_HEADER = "REMOTE_USER"; + private String keystorePath = "/tmp/samlKeystore.jks"; private String keystorePassword = "changeit"; private String privateKeyPassword = "changeit"; @@ -22,7 +24,7 @@ public class Pac4jConfigurationProperties { private boolean wantAssertionsSigned = true; private SAML2ProfileMapping saml2ProfileMapping; private String typeOfAuth = "SAML2"; - private String authenticationHeader = "REMOTE_USER"; + private String authenticationHeader = DEFAULT_AUTH_HEADER; public static class SAML2ProfileMapping { private String username; diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index fc3a7c081..812a20e09 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -82,19 +82,15 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository use @Override protected void configure(HttpSecurity http) throws Exception { - final SecurityFilter securityFilter = new SecurityFilter(this.config, "Saml2Client"); final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, "HeaderClient"); final CallbackFilter callbackFilter = new CallbackFilter(this.config); http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class) - .addFilterBefore(securityFilter, BasicAuthenticationFilter.class) .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) //xxx check on this .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); - http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); - http.csrf().disable(); http.headers().frameOptions().disable(); } From 3e29f8120db3b8e079621e6a3be21af818bf4393 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Sat, 26 Jun 2021 09:57:56 -0700 Subject: [PATCH 06/18] SHIBUI-1774 Updated libs for pac4j to current and updated related configurations --- pac4j-module/build.gradle | 7 +- .../shibui/pac4j/Pac4jConfiguration.java | 109 +++++++++++------- .../SAML2ModelAuthorizationGenerator.java | 10 +- .../net/unicon/shibui/pac4j/WebSecurity.java | 41 +------ 4 files changed, 85 insertions(+), 82 deletions(-) diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index 18eb7be38..9849aa614 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -25,10 +25,9 @@ dependencyManagement { dependencies { compileOnly project(':backend') - compile "org.pac4j:spring-security-pac4j:4.0.0" - compile "org.pac4j:pac4j-http:4.0.0" - compile "org.pac4j:pac4j-core:3.3.0" - compile "org.pac4j:pac4j-saml:3.3.0", { + compile "org.pac4j:spring-security-pac4j:6.0.0" + compile "org.pac4j:pac4j-http:5.1.0" + compile "org.pac4j:pac4j-saml:5.1.0", { // opensaml libraries are provided exclude group: 'org.opensaml' } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index c885f0049..de8db70a7 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -1,77 +1,108 @@ package net.unicon.shibui.pac4j; -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; +import org.apache.commons.lang3.StringUtils; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; import org.pac4j.core.context.WebContext; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.credentials.Credentials; import org.pac4j.core.credentials.TokenCredentials; import org.pac4j.core.credentials.authenticator.Authenticator; import org.pac4j.core.exception.CredentialsException; -import org.pac4j.core.profile.CommonProfile; +import org.pac4j.core.matching.matcher.PathMatcher; import org.pac4j.core.profile.definition.CommonProfileDefinition; -import org.pac4j.http.client.direct.ParameterClient; +import org.pac4j.http.client.direct.HeaderClient; import org.pac4j.saml.client.SAML2Client; -import org.pac4j.saml.client.SAML2ClientConfiguration; +import org.pac4j.saml.config.SAML2Configuration; import org.pac4j.saml.credentials.authenticator.SAML2Authenticator; -import org.pac4j.http.client.direct.HeaderClient; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.google.common.collect.Lists; + +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; + +/** + * Configuration setup here following readme from - https://github.com/pac4j/spring-security-pac4j/tree/5.0.x + * NOTE: matchers are now done as part of the config and have been moved over from the WebSecurity.java class of this package + * @see http://www.pac4j.org/docs/config.html + */ @Configuration @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") public class Pac4jConfiguration { + public final static String PAC4J_CLIENT_NAME = "shibUIAuthClient"; + + /** + * Custom class that ensures we add the user's roles to the information when doing SAML2 auth + */ @Bean public SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator(UserRepository userRepository) { return new SAML2ModelAuthorizationGenerator(userRepository); } - + @Bean - public Config config(final Pac4jConfigurationProperties pac4jConfigurationProperties, - final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { + public Config config(final Pac4jConfigurationProperties pac4jConfigProps, + final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { - final Clients clients = new Clients(pac4jConfigurationProperties.getCallbackUrl()); + final Clients clients = new Clients(pac4jConfigProps.getCallbackUrl()); - if (pac4jConfigurationProperties.getTypeOfAuth().equals("SAML2")) { - final SAML2ClientConfiguration saml2ClientConfiguration = new SAML2ClientConfiguration(); - saml2ClientConfiguration.setKeystorePath(pac4jConfigurationProperties.getKeystorePath()); - saml2ClientConfiguration.setKeystorePassword(pac4jConfigurationProperties.getKeystorePassword()); - saml2ClientConfiguration.setPrivateKeyPassword(pac4jConfigurationProperties.getPrivateKeyPassword()); - saml2ClientConfiguration.setIdentityProviderMetadataPath(pac4jConfigurationProperties.getIdentityProviderMetadataPath()); - saml2ClientConfiguration.setMaximumAuthenticationLifetime(pac4jConfigurationProperties.getMaximumAuthenticationLifetime()); - saml2ClientConfiguration.setServiceProviderEntityId(pac4jConfigurationProperties.getServiceProviderEntityId()); - saml2ClientConfiguration.setServiceProviderMetadataPath(pac4jConfigurationProperties.getServiceProviderMetadataPath()); - saml2ClientConfiguration.setForceServiceProviderMetadataGeneration(pac4jConfigurationProperties.isForceServiceProviderMetadataGeneration()); - saml2ClientConfiguration.setWantsAssertionsSigned(pac4jConfigurationProperties.isWantAssertionsSigned()); - saml2ClientConfiguration.setAttributeAsId(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()); + // Configure the client + switch (pac4jConfigProps.getTypeOfAuth()) { + case "SAML2": { + final SAML2Configuration saml2Config = new SAML2Configuration(); + saml2Config.setKeystorePath(pac4jConfigProps.getKeystorePath()); + saml2Config.setKeystorePassword(pac4jConfigProps.getKeystorePassword()); + saml2Config.setPrivateKeyPassword(pac4jConfigProps.getPrivateKeyPassword()); + saml2Config.setIdentityProviderMetadataPath(pac4jConfigProps.getIdentityProviderMetadataPath()); + saml2Config.setMaximumAuthenticationLifetime(pac4jConfigProps.getMaximumAuthenticationLifetime()); + saml2Config.setServiceProviderEntityId(pac4jConfigProps.getServiceProviderEntityId()); + saml2Config.setServiceProviderMetadataPath(pac4jConfigProps.getServiceProviderMetadataPath()); + saml2Config.setForceServiceProviderMetadataGeneration(pac4jConfigProps.isForceServiceProviderMetadataGeneration()); + saml2Config.setWantsAssertionsSigned(pac4jConfigProps.isWantAssertionsSigned()); + saml2Config.setAttributeAsId(pac4jConfigProps.getSaml2ProfileMapping().getUsername()); + //saml2Config.setPostLogoutURL(pac4jConfigProps.getPostLogoutURL()); // consideration needed? + //saml2Config.setSpLogoutRequestBindingType(pac4jConfigProps.getSpLogoutRequestBindingType()); - final SAML2Client saml2Client = new SAML2Client(saml2ClientConfiguration); + final SAML2Client saml2Client = new SAML2Client(saml2Config); saml2Client.setName("Saml2Client"); saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); - SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2ClientConfiguration.getAttributeAsId(), - saml2ClientConfiguration.getMappedAttributes()); - saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>( - p -> new BetterSAML2Profile(pac4jConfigurationProperties.getSaml2ProfileMapping().getUsername()))); + SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2Config.getAttributeAsId(), saml2Config.getMappedAttributes()); +// saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>(p -> new BetterSAML2Profile(pac4jConfigProps.getSaml2ProfileMapping().getUsername()))); saml2Client.setAuthenticator(saml2Authenticator); + saml2Client.setName(PAC4J_CLIENT_NAME); clients.setClients(saml2Client); - } else if (pac4jConfigurationProperties.getTypeOfAuth().equals("HEADER")) { - HeaderClient headerClient = new HeaderClient(pac4jConfigurationProperties.getAuthenticationHeader(), new Authenticator() { - @Override - public void validate(Credentials credentials, WebContext context) { - if (credentials instanceof TokenCredentials) { - TokenCredentials creds = (TokenCredentials) credentials; - String remoteUser = creds.getToken(); - } else { - throw new CredentialsException("Invalid Credentials object generated by HeaderClient"); - } - } - }); + } + case "HEADER": { + HeaderClient headerClient = new HeaderClient(pac4jConfigProps.getAuthenticationHeader(), + new Authenticator() { + @Override + public void validate(Credentials credentials, WebContext context, SessionStore sessionStore) { + if (credentials instanceof TokenCredentials) { + TokenCredentials creds = (TokenCredentials) credentials; + String token = creds.getToken(); + if (StringUtils.isAllBlank(token)) { + throw new CredentialsException("Supplied token value in header was missing or blank"); + } + } else { + throw new CredentialsException("Invalid Credentials object generated by HeaderClient"); + } + // must set user profile on credentials in order to continue. + // credentials.setUserProfile(userProfile); + } + }); + headerClient.setName(PAC4J_CLIENT_NAME); clients.setClients(headerClient); } - + } final Config config = new Config(clients); + + // configure the matcher for bypassing auth checks + PathMatcher pm = new PathMatcher(); + pm.setExcludedPaths(Lists.newArrayList("/favicon.ico", "/unsecured/**/*", "/error")); + config.addMatcher("exclude-paths-matcher", pm); + return config; } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java index 165477627..4286d4e38 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java @@ -4,11 +4,13 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import org.pac4j.core.authorization.generator.AuthorizationGenerator; import org.pac4j.core.context.WebContext; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.core.profile.UserProfile; import org.pac4j.saml.profile.SAML2Profile; import java.util.Optional; -public class SAML2ModelAuthorizationGenerator implements AuthorizationGenerator { +public class SAML2ModelAuthorizationGenerator implements AuthorizationGenerator { private final UserRepository userRepository; public SAML2ModelAuthorizationGenerator(UserRepository userRepository) { @@ -16,9 +18,9 @@ public SAML2ModelAuthorizationGenerator(UserRepository userRepository) { } @Override - public SAML2Profile generate(WebContext context, SAML2Profile profile) { + public Optional generate(WebContext context, SessionStore sessionStore, UserProfile profile) { Optional user = userRepository.findByUsername(profile.getUsername()); - user.ifPresent( u -> profile.addRole(u.getRole())); - return profile; + user.ifPresent( u -> ((SAML2Profile)profile).addRole(u.getRole())); + return Optional.of(profile); } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 812a20e09..7e17031f5 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -4,9 +4,11 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; + import org.pac4j.core.config.Config; import org.pac4j.springframework.security.web.CallbackFilter; import org.pac4j.springframework.security.web.SecurityFilter; + import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -20,50 +22,19 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.firewall.StrictHttpFirewall; -import javax.swing.text.html.Option; import java.util.Optional; @Configuration @AutoConfigureOrder(-1) @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") @AutoConfigureAfter(EmailConfiguration.class) - public class WebSecurity { + @Bean("webSecurityConfig") public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository, Optional emailService, Pac4jConfigurationProperties pac4jConfigurationProperties) { return new Pac4jWebSecurityConfigurerAdapter(config, userRepository, roleRepository, emailService, pac4jConfigurationProperties); } - @Configuration - @Order(0) - @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") - public static class FaviconSecurityConfiguration extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/favicon.ico").authorizeRequests().antMatchers("/favicon.ico").permitAll(); - } - } - - @Configuration - @Order(1) - @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") - public static class UnsecuredSecurityConfiguration extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/unsecured/**/*").authorizeRequests().antMatchers("/unsecured/**/*").permitAll(); - } - } - - @Configuration - @Order(2) - @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") - public static class ErrorSecurityConfiguration extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/error").authorizeRequests().antMatchers("/error").permitAll(); - } - } - @Order(100) public static class Pac4jWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { private final Config config; @@ -82,12 +53,12 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository use @Override protected void configure(HttpSecurity http) throws Exception { - final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, "HeaderClient"); + final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, Pac4jConfiguration.PAC4J_CLIENT_NAME); final CallbackFilter callbackFilter = new CallbackFilter(this.config); http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class) - .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) //xxx check on this - .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); + .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) //xxx check on this + .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); From c252b63355d9a94f55c32b1c15796933a0a51daf Mon Sep 17 00:00:00 2001 From: chasegawa Date: Sat, 26 Jun 2021 10:33:51 -0700 Subject: [PATCH 07/18] SHIBUI-1774 Missed correction --- .../main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index de8db70a7..070265867 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -68,7 +68,7 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps, saml2Client.setName("Saml2Client"); saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2Config.getAttributeAsId(), saml2Config.getMappedAttributes()); -// saml2Authenticator.setProfileDefinition(new CommonProfileDefinition<>(p -> new BetterSAML2Profile(pac4jConfigProps.getSaml2ProfileMapping().getUsername()))); + saml2Authenticator.setProfileDefinition(new CommonProfileDefinition(p -> new BetterSAML2Profile(pac4jConfigProps.getSaml2ProfileMapping().getUsername()))); saml2Client.setAuthenticator(saml2Authenticator); saml2Client.setName(PAC4J_CLIENT_NAME); From 0a6d994403e7ee9d48f57045ea713e17b32bb6e3 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Sat, 26 Jun 2021 10:41:31 -0700 Subject: [PATCH 08/18] SHIBUI-1774 minor cleanup --- pac4j-module/build.gradle | 2 +- .../src/main/java/net/unicon/shibui/pac4j/WebSecurity.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index 9849aa614..f0c6f87fa 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -25,7 +25,7 @@ dependencyManagement { dependencies { compileOnly project(':backend') - compile "org.pac4j:spring-security-pac4j:6.0.0" + compile "org.pac4j:spring-security-pac4j:6.0.0" // pac4j is "off" - spring 6.0.0 here uses 5.1 core, thus differences in versions compile "org.pac4j:pac4j-http:5.1.0" compile "org.pac4j:pac4j-saml:5.1.0", { // opensaml libraries are provided diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 7e17031f5..da34a58ff 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -57,7 +57,7 @@ protected void configure(HttpSecurity http) throws Exception { final CallbackFilter callbackFilter = new CallbackFilter(this.config); http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class) - .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) //xxx check on this + .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); From 6ff066fc4b4be323e55ed7d2f6e7a68c7cfa671f Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 7 Jul 2021 12:29:23 -0700 Subject: [PATCH 09/18] SHIBUI-1744 Updated to handle incoming header auth --- pac4j-module/build.gradle | 5 +- .../unicon/shibui/pac4j/AddNewUserFilter.java | 64 +++++++++---------- .../shibui/pac4j/Pac4jConfiguration.java | 7 +- .../net/unicon/shibui/pac4j/WebSecurity.java | 1 + 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index f0c6f87fa..4318595df 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -1,8 +1,9 @@ plugins { id 'groovy' id 'jacoco' - id 'org.springframework.boot' version '2.1.5.RELEASE' apply false + id 'org.springframework.boot' version '2.4.2' apply false id 'io.spring.dependency-management' version '1.0.7.RELEASE' + id 'io.freefair.lombok' version '5.3.0' } sourceCompatibility = 11 @@ -22,6 +23,8 @@ dependencyManagement { } } +generateLombokConfig.enabled = false + dependencies { compileOnly project(':backend') diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java index 54cb2950d..7ca2c3676 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java @@ -7,7 +7,9 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; + import org.apache.commons.lang3.RandomStringUtils; +import org.pac4j.core.profile.CommonProfile; import org.pac4j.saml.profile.SAML2Profile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,22 +29,17 @@ import java.util.List; import java.util.Optional; -/** - * @author Bill Smith (wsmith@unicon.net) - */ -public class AddNewUserFilter implements Filter { - - private static final Logger logger = LoggerFactory.getLogger(AddNewUserFilter.class); +import lombok.extern.slf4j.Slf4j; +@Slf4j +public class AddNewUserFilter implements Filter { private static final String ROLE_NONE = "ROLE_NONE"; - private UserRepository userRepository; - private RoleRepository roleRepository; private Optional emailService; - private Pac4jConfigurationProperties pac4jConfigurationProperties; - + private RoleRepository roleRepository; private Pac4jConfigurationProperties.SAML2ProfileMapping saml2ProfileMapping; + private UserRepository userRepository; public AddNewUserFilter(Pac4jConfigurationProperties pac4jConfigurationProperties, UserRepository userRepository, RoleRepository roleRepository, Optional emailService) { this.userRepository = userRepository; @@ -52,11 +49,7 @@ public AddNewUserFilter(Pac4jConfigurationProperties pac4jConfigurationPropertie saml2ProfileMapping = this.pac4jConfigurationProperties.getSaml2ProfileMapping(); } - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - private User buildAndPersistNewUserFromProfile(SAML2Profile profile) { + private User buildAndPersistNewUserFromProfile(CommonProfile profile) { Role noRole = roleRepository.findByName(ROLE_NONE).orElse(new Role(ROLE_NONE)); roleRepository.save(noRole); @@ -68,16 +61,20 @@ private User buildAndPersistNewUserFromProfile(SAML2Profile profile) { user.setLastName(getAttributeFromProfile(profile, "lastName")); user.setEmailAddress(getAttributeFromProfile(profile, "email")); User persistedUser = userRepository.save(user); - if (logger.isDebugEnabled()) { - logger.debug("Persisted new user:\n" + user); + if (log.isDebugEnabled()) { + log.debug("Persisted new user:\n" + user); } return persistedUser; } + @Override + public void destroy() { + } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - SAML2Profile profile = (SAML2Profile) authentication.getPrincipal(); + CommonProfile profile = (CommonProfile) authentication.getPrincipal(); if (profile != null) { String username = getAttributeFromProfile(profile, "username"); if (username != null) { @@ -89,7 +86,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha try { e.sendNewUserMail(username); } catch (MessagingException e1) { - logger.warn(String.format("Unable to send new user email for user [%s]", username), e); + log.warn(String.format("Unable to send new user email for user [%s]", username), e); } }); } else { @@ -104,34 +101,37 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } } - @Override - public void destroy() { + private String getAttributeFromProfile(CommonProfile profile, String stringKey) { + if (profile instanceof SAML2Profile) { + return getAttributeFromSAML2Profile(profile, stringKey); + } + return stringKey.equalsIgnoreCase("username") ? profile.getId() : null; } - - private String getAttributeFromProfile(SAML2Profile profile, String stringKey) { - String attribute = null; + + @SuppressWarnings("unchecked") + private String getAttributeFromSAML2Profile(CommonProfile profile, String stringKey) { + String attributeKey = null; switch (stringKey) { case "username": - attribute = saml2ProfileMapping.getUsername(); + attributeKey = saml2ProfileMapping.getUsername(); break; case "firstName": - attribute = saml2ProfileMapping.getFirstName(); + attributeKey = saml2ProfileMapping.getFirstName(); break; case "lastName": - attribute = saml2ProfileMapping.getLastName(); + attributeKey = saml2ProfileMapping.getLastName(); break; case "email": - attribute = saml2ProfileMapping.getEmail(); + attributeKey = saml2ProfileMapping.getEmail(); break; default: // do we care? Not yet. } - List attributeList = (List) profile.getAttribute(attribute); + List attributeList = (List) profile.getAttribute(attributeKey); return attributeList.size() < 1 ? null : attributeList.get(0); } - private byte[] getJsonResponseBytes(ErrorResponse eErrorResponse) throws IOException { - String errorResponseJson = new ObjectMapper().writeValueAsString(eErrorResponse); - return errorResponseJson.getBytes(); + @Override + public void init(FilterConfig filterConfig) throws ServletException { } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index 070265867..4b0939acc 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -10,6 +10,7 @@ import org.pac4j.core.credentials.authenticator.Authenticator; import org.pac4j.core.exception.CredentialsException; import org.pac4j.core.matching.matcher.PathMatcher; +import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.definition.CommonProfileDefinition; import org.pac4j.http.client.direct.HeaderClient; import org.pac4j.saml.client.SAML2Client; @@ -88,8 +89,10 @@ public void validate(Credentials credentials, WebContext context, SessionStore s } else { throw new CredentialsException("Invalid Credentials object generated by HeaderClient"); } - // must set user profile on credentials in order to continue. - // credentials.setUserProfile(userProfile); + final CommonProfile profile = new CommonProfile(); + String token = ((TokenCredentials)credentials).getToken(); + profile.setId(token); + credentials.setUserProfile(profile); } }); headerClient.setName(PAC4J_CLIENT_NAME); diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index da34a58ff..c29f170c3 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -72,6 +72,7 @@ public void configure(org.springframework.security.config.annotation.web.builder StrictHttpFirewall firewall = new StrictHttpFirewall(); firewall.setAllowUrlEncodedSlash(true); + firewall.setAllowUrlEncodedDoubleSlash(true); web.httpFirewall(firewall); } } From 3bcc0c93adddb97b4e1875584d143f2cfb67fb7c Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 7 Jul 2021 15:58:29 -0700 Subject: [PATCH 10/18] SHIBUI-1744 Adjusting the configuration and setup --- .../unicon/shibui/pac4j/AddNewUserFilter.java | 47 ++++++++++--------- .../shibui/pac4j/Pac4jConfiguration.java | 2 +- .../net/unicon/shibui/pac4j/WebSecurity.java | 22 +++++---- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java index 7ca2c3676..aca51e6fc 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java @@ -74,28 +74,31 @@ public void destroy() { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - CommonProfile profile = (CommonProfile) authentication.getPrincipal(); - if (profile != null) { - String username = getAttributeFromProfile(profile, "username"); - if (username != null) { - Optional persistedUser = userRepository.findByUsername(username); - User user; - if (!persistedUser.isPresent()) { - user = buildAndPersistNewUserFromProfile(profile); - emailService.ifPresent(e -> { - try { - e.sendNewUserMail(username); - } catch (MessagingException e1) { - log.warn(String.format("Unable to send new user email for user [%s]", username), e); - } - }); - } else { - user = persistedUser.get(); - } - if (user.getRole().equals(ROLE_NONE)) { - ((HttpServletResponse) response).sendRedirect("/unsecured/error.html"); - } else { - chain.doFilter(request, response); // else, user is in the system already, carry on + if (authentication != null) { + CommonProfile profile = (CommonProfile) authentication.getPrincipal(); + if (profile != null) { + String username = getAttributeFromProfile(profile, "username"); + if (username != null) { + Optional persistedUser = userRepository.findByUsername(username); + User user; + if (!persistedUser.isPresent()) { + user = buildAndPersistNewUserFromProfile(profile); + emailService.ifPresent(e -> { + try { + e.sendNewUserMail(username); + } + catch (MessagingException e1) { + log.warn(String.format("Unable to send new user email for user [%s]", username), e); + } + }); + } else { + user = persistedUser.get(); + } + if (user.getRole().equals(ROLE_NONE)) { + ((HttpServletResponse) response).sendRedirect("/unsecured/error.html"); + } else { + chain.doFilter(request, response); // else, user is in the system already, carry on + } } } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index 4b0939acc..f8f5f6a55 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -103,7 +103,7 @@ public void validate(Credentials credentials, WebContext context, SessionStore s // configure the matcher for bypassing auth checks PathMatcher pm = new PathMatcher(); - pm.setExcludedPaths(Lists.newArrayList("/favicon.ico", "/unsecured/**/*", "/error")); + pm.setExcludedPaths(Lists.newArrayList("/favicon.ico", "/unsecured/**/*", "/error", "/login", "/")); config.addMatcher("exclude-paths-matcher", pm); return config; diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index c29f170c3..882c33df9 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -29,10 +29,13 @@ @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") @AutoConfigureAfter(EmailConfiguration.class) public class WebSecurity { - + @Bean("webSecurityConfig") - public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository, Optional emailService, Pac4jConfigurationProperties pac4jConfigurationProperties) { - return new Pac4jWebSecurityConfigurerAdapter(config, userRepository, roleRepository, emailService, pac4jConfigurationProperties); + public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository, + RoleRepository roleRepository, Optional emailService, + Pac4jConfigurationProperties pac4jConfigurationProperties) { + return new Pac4jWebSecurityConfigurerAdapter(config, userRepository, roleRepository, emailService, + pac4jConfigurationProperties); } @Order(100) @@ -43,7 +46,8 @@ public static class Pac4jWebSecurityConfigurerAdapter extends WebSecurityConfigu private Optional emailService; private Pac4jConfigurationProperties pac4jConfigurationProperties; - public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository, Optional emailService, Pac4jConfigurationProperties pac4jConfigurationProperties) { + public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository, + Optional emailService, Pac4jConfigurationProperties pac4jConfigurationProperties) { this.config = config; this.userRepository = userRepository; this.roleRepository = roleRepository; @@ -54,12 +58,14 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository use @Override protected void configure(HttpSecurity http) throws Exception { final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, Pac4jConfiguration.PAC4J_CLIENT_NAME); - + securityFilterForHeader.setMatchers("exclude-paths-matcher"); + final CallbackFilter callbackFilter = new CallbackFilter(this.config); + http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class) - .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) - .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); - + .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) + .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, + emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); http.csrf().disable(); From d0d227a75ac02262e09bee275d28cf8915794284 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Wed, 7 Jul 2021 16:47:02 -0700 Subject: [PATCH 11/18] SHIBUI-1774 Continued efforts to get configuration correct --- .../java/net/unicon/shibui/pac4j/WebSecurity.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index 882c33df9..fc8532196 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -5,10 +5,11 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; +import org.apache.commons.lang3.StringUtils; import org.pac4j.core.config.Config; import org.pac4j.springframework.security.web.CallbackFilter; import org.pac4j.springframework.security.web.SecurityFilter; - +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -21,6 +22,7 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.firewall.StrictHttpFirewall; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import java.util.Optional; @@ -29,7 +31,9 @@ @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") @AutoConfigureAfter(EmailConfiguration.class) public class WebSecurity { - + @Value("${shibui.logout-url:/dashboard}") + private static String logoutUrl; + @Bean("webSecurityConfig") public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository, Optional emailService, @@ -67,6 +71,11 @@ protected void configure(HttpSecurity http) throws Exception { .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); + + http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> response.sendRedirect("/unsecured/error.html")) + .and().formLogin().and().httpBasic().and() + .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl(StringUtils.isAllEmpty(logoutUrl) ? "/dashboard" : logoutUrl); + http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); http.csrf().disable(); http.headers().frameOptions().disable(); From 57eb294e6503894ad29f8c3fabfcca0ad01dc500 Mon Sep 17 00:00:00 2001 From: Jj! Date: Thu, 8 Jul 2021 15:17:49 -0500 Subject: [PATCH 12/18] [SHIBUI-1774] test environment --- .../test/docker/conf-header/application.yml | 12 +++++ .../src/test/docker/conf-header/users.csv | 1 + .../src/test/docker/docker-compose-header.yml | 44 +++++++++++++++++++ .../reverse-proxy/certs/star.unicon.local.crt | 19 ++++++++ .../reverse-proxy/certs/star.unicon.local.key | 28 ++++++++++++ .../configuration/certificates.yml | 9 ++++ 6 files changed, 113 insertions(+) create mode 100644 pac4j-module/src/test/docker/conf-header/application.yml create mode 100644 pac4j-module/src/test/docker/conf-header/users.csv create mode 100644 pac4j-module/src/test/docker/docker-compose-header.yml create mode 100644 pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.crt create mode 100644 pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.key create mode 100644 pac4j-module/src/test/docker/reverse-proxy/configuration/certificates.yml diff --git a/pac4j-module/src/test/docker/conf-header/application.yml b/pac4j-module/src/test/docker/conf-header/application.yml new file mode 100644 index 000000000..252f055e2 --- /dev/null +++ b/pac4j-module/src/test/docker/conf-header/application.yml @@ -0,0 +1,12 @@ +shibui: + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_PONY + pac4j-enabled: true + pac4j: + type-of-auth: HEADER + authentication-header: REMOTE_USER + +logging: + level: + org.pac4j: "TRACE" + org.opensaml: "INFO" diff --git a/pac4j-module/src/test/docker/conf-header/users.csv b/pac4j-module/src/test/docker/conf-header/users.csv new file mode 100644 index 000000000..fcd838992 --- /dev/null +++ b/pac4j-module/src/test/docker/conf-header/users.csv @@ -0,0 +1 @@ +admin,{noop}password,test,test,ROLE_ADMIN,test@example.com diff --git a/pac4j-module/src/test/docker/docker-compose-header.yml b/pac4j-module/src/test/docker/docker-compose-header.yml new file mode 100644 index 000000000..0b978fcda --- /dev/null +++ b/pac4j-module/src/test/docker/docker-compose-header.yml @@ -0,0 +1,44 @@ +version: "3.7" + +services: + reverse-proxy: + image: library/traefik:v2.2 + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web-secure.address=:443" + - "--providers.file.directory=/configuration/" + - "--providers.file.watch=true" + # - "--log.level=DEBUG" + networks: + - reverse-proxy + ports: + - "80:80" + - "8080:8080" + - "443:443" + - "8443:8443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./reverse-proxy/:/configuration/ + - ./reverse-proxy/certs/:/certs/ + shibui: + image: unicon/shibui + entrypoint: ["/usr/bin/java", "-Dspring.profiles.active=dev", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-jar", "app.war"] + labels: + - "traefik.http.routers.shibui.rule=Host(`shibui.unicon.local`)" + - "traefik.http.services.shibui.loadbalancer.server.port=8080" + - "traefik.http.routers.shibui.tls=true" + - "traefik.docker.network=docker_reverse-proxy" + - "traefik.enable=true" + - "traefik.http.middlewares.header.headers.customRequestHeaders.REMOTE_USER=admin" + - "traefik.http.routers.shibui.middlewares=header" + ports: + - 5005:5005 + networks: + - reverse-proxy + volumes: + - ./conf-header:/conf + - ./conf-header/application.yml:/application.yml +networks: + reverse-proxy: diff --git a/pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.crt b/pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.crt new file mode 100644 index 000000000..8d4592789 --- /dev/null +++ b/pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCDCCAfCgAwIBAgIJANdpvkovSXs6MA0GCSqGSIb3DQEBCwUAMBkxFzAVBgNV +BAMMDioudW5pY29uLmxvY2FsMB4XDTIwMDUyNzE3MzE1OVoXDTMwMDUyNzE3MzE1 +OVowGTEXMBUGA1UEAwwOKi51bmljb24ubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCh9zduMpOqWDPfx5vHSBoWDwk44cc8XdFCD7nqi9EPHewO +jAKCVihWKGa3OX6kQ4g6VIE7PCqdvtjq6eJ54FKuJ7FiFQweuaUXlXx5tdiWYfVe ++BV7jaLJGy0iniPgx8Pu9ajQOOINcmLwixYkTe+OBfeMgeivk0+o58/Lmkl2FyAv +IvGA2Glxf8QtxQwHgtQLU3aHRlgi6YHSIxolvX+CuDvj4xsgLBdCphYkJtUXmaKO +frQRxnHVxUUptWptqbwJPxrOMnIIdteRnduo+/i0RZ33+tC5W61Cr2uyoDGUzmKE +HKgfTMxLeqJLtm+sB74xmI3Fsnq3qfWajZLqUyz5AgMBAAGjUzBRMB0GA1UdDgQW +BBROeSN15J2wAW9OMZAdPIz84DEOsjAfBgNVHSMEGDAWgBROeSN15J2wAW9OMZAd +PIz84DEOsjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQASo38W +sqw8vijAs3DSYUCjFjlAvlwjsXU0y4IpelmgYSWD0Lqfb9/5jEu06F8hzLMSzmAL +4UKIX6TwtLQb3HLvYObbjhaSSYG0Tl702dANW499QlHF/gYsCb9C6oA+5jzfHd7Y +LS8bUv6gZkC3rP1E0kCGLJGrtvdMniAPuZ8W25SFedpR0iR7+d+lg9oOBsgjkWGc +eKNtSJvic5dyZQCDlEzXVa3lyBOrawW9J/Sqhm0v3Tar1CVKoeXU3QV/bx7s8TWH +YvaxQ82dOsGwZDMmPHhnJQDIQqjt2H9RJjrJy440RwyLiDr1A3/AJxrqpz98QONG +FOhuJQXDH3YGDP7B +-----END CERTIFICATE----- diff --git a/pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.key b/pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.key new file mode 100644 index 000000000..204200812 --- /dev/null +++ b/pac4j-module/src/test/docker/reverse-proxy/certs/star.unicon.local.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCh9zduMpOqWDPf +x5vHSBoWDwk44cc8XdFCD7nqi9EPHewOjAKCVihWKGa3OX6kQ4g6VIE7PCqdvtjq +6eJ54FKuJ7FiFQweuaUXlXx5tdiWYfVe+BV7jaLJGy0iniPgx8Pu9ajQOOINcmLw +ixYkTe+OBfeMgeivk0+o58/Lmkl2FyAvIvGA2Glxf8QtxQwHgtQLU3aHRlgi6YHS +IxolvX+CuDvj4xsgLBdCphYkJtUXmaKOfrQRxnHVxUUptWptqbwJPxrOMnIIdteR +nduo+/i0RZ33+tC5W61Cr2uyoDGUzmKEHKgfTMxLeqJLtm+sB74xmI3Fsnq3qfWa +jZLqUyz5AgMBAAECggEAD5EuT7YmwTmnCrwpudaxQyuAzGnO93tg8IOIcAWuO1C5 +7pAAcbyMNfO+I6AwDuO6xTh4D1RyGCVOvg1qyiIIcFq6Tt4NAyr+tiyVATG8NoAF +0HHxxqVPXxrwlKI0epdYuq/74L+G4pn67nm/0A95leH28BdQYQe8oVRegYg7xVC+ +hFNQATLro1NXPfOtujn47/HjIHBBd2Or6dgj/Jh0niFg6Ts3LCgoxZVJeOVTqFht +26tpyMygeE2UpDIDlJjpO+YWTBIMV2i5MuoDAjQDlunaWyrz+Uo4LHaqGrBKkqri +3qhcWI0mGDIw4JPupNStpKXsOBdDCobi80taaKIIgQKBgQDVgVLOAKJu2xMH3/k/ +Fkj1GOugJ+cFvNiXZbwsxc3T5v5InoBeit4MoHSbATFt5EM4oxRD0LOAnkkdJAS3 +2k3nwQkBxR+AWc/9Tugxtyg84oaMrQ3kgwVMWEyFfDjtnAXzJ/vhUvkLaQXKRuW4 +Bpmd0BfZTVmnD6o7KAjCVoBVsQKBgQDCM9CIG6rJ7gxkd0tOOfIXcReG8jGve1tG +8WDg6JhdL/ITBx4y6m9ez/P9BNn9BJixCbkkcwvRro/pCYZG7rNWQsr/9AxiUk/a +91oaGyiPhe6ly5/HlaIyUBPejr3clPL29UFe7CEWiuc/DdhuIrblWziSaX5K8n9d +C85ECkZ1yQKBgDPgfHI5jT5KVNFxBmrhy1Bigb4kc+nc/POscJCgb2axlc+nU6Gl +NFb1FeAj5hLBh+PXHDFuIG98Bl/iRJM3o/5P1RRtBT52lCcEaT7LNie1EuRTmDCR +9VObkNxOVrbFVlzCtl0FgCXZmuKPX3nbgK/rxB+0v7fsAnzlOVufEQfBAoGAUSkQ +ZGGTrdJzkWUdrrKez1cvKvF6/EiEbBCimTv7uS45b+RQpZy+MJSd9kcZxxktqwdS +Pb5q2RWoBQ8689f8UPeXGQLoTgryXqNzH2fsOpcRlm6T9vg9EePPefqTtGT3aWg0 +CrSKW35viDWEFvshDpdh/CZkZnQT8FHnwR2+NqkCgYEAh9ZygpT21hZGMPUjk8j8 +Qo8+K33p08+Sf4LsSQMy9uq5+rcZ3/0S/bZeSHSQgVxba1S61WvE3MGz779f3A8U +GKUnCR9HfZpbw2ziVzKsJUqfq9q1bsy3LSJUNfJfEJWshSh8DNCyDv/y4HON53Il +yOQugjsEbN6Be3D0FBCFYlc= +-----END PRIVATE KEY----- diff --git a/pac4j-module/src/test/docker/reverse-proxy/configuration/certificates.yml b/pac4j-module/src/test/docker/reverse-proxy/configuration/certificates.yml new file mode 100644 index 000000000..88abe448d --- /dev/null +++ b/pac4j-module/src/test/docker/reverse-proxy/configuration/certificates.yml @@ -0,0 +1,9 @@ +tls: + certificates: + - certFile: /certs/star.unicon.local.crt + keyFile: /certs/star.unicon.local.key + stores: + default: + defaultCertificate: + certFile: /certs/star.unicon.local.crt + keyFile: /certs/star.unicon.local.key \ No newline at end of file From 401dbf925b2b635dfac93dcd324e7a48c1fca904 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 9 Jul 2021 14:40:38 -0700 Subject: [PATCH 13/18] SHIBUI-1748 Finally got the configuration working --- .../shibui/pac4j/Pac4jConfiguration.java | 15 +- .../pac4j/Pac4jConfigurationProperties.java | 169 +++--------------- .../net/unicon/shibui/pac4j/WebSecurity.java | 38 ++-- 3 files changed, 53 insertions(+), 169 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index f8f5f6a55..ac3f159c2 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -16,6 +16,7 @@ import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.config.SAML2Configuration; import org.pac4j.saml.credentials.authenticator.SAML2Authenticator; +import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -24,6 +25,8 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; +import lombok.extern.slf4j.Slf4j; + /** * Configuration setup here following readme from - https://github.com/pac4j/spring-security-pac4j/tree/5.0.x * NOTE: matchers are now done as part of the config and have been moved over from the WebSecurity.java class of this package @@ -31,6 +34,7 @@ */ @Configuration @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") +@Slf4j public class Pac4jConfiguration { public final static String PAC4J_CLIENT_NAME = "shibUIAuthClient"; @@ -42,15 +46,17 @@ public SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator(UserRep return new SAML2ModelAuthorizationGenerator(userRepository); } - @Bean + @Bean(name = "pac4j-config") public Config config(final Pac4jConfigurationProperties pac4jConfigProps, - final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { - + final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { + log.info("**** Configuring PAC4J "); + final Config config = new Config(); final Clients clients = new Clients(pac4jConfigProps.getCallbackUrl()); // Configure the client switch (pac4jConfigProps.getTypeOfAuth()) { case "SAML2": { + log.info("**** Configuring PAC4J SAML2"); final SAML2Configuration saml2Config = new SAML2Configuration(); saml2Config.setKeystorePath(pac4jConfigProps.getKeystorePath()); saml2Config.setKeystorePassword(pac4jConfigProps.getKeystorePassword()); @@ -76,6 +82,7 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps, clients.setClients(saml2Client); } case "HEADER": { + log.info("**** Configuring PAC4J Header Client"); HeaderClient headerClient = new HeaderClient(pac4jConfigProps.getAuthenticationHeader(), new Authenticator() { @Override @@ -99,13 +106,13 @@ public void validate(Credentials credentials, WebContext context, SessionStore s clients.setClients(headerClient); } } - final Config config = new Config(clients); // configure the matcher for bypassing auth checks PathMatcher pm = new PathMatcher(); pm.setExcludedPaths(Lists.newArrayList("/favicon.ico", "/unsecured/**/*", "/error", "/login", "/")); config.addMatcher("exclude-paths-matcher", pm); + config.setClients(clients); return config; } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 57e38d91b..8a44baf47 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -1,172 +1,47 @@ package net.unicon.shibui.pac4j; +import javax.servlet.Filter; + +import org.pac4j.springframework.security.web.CallbackFilter; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Component; +import lombok.Getter; +import lombok.Setter; + @Component @ConfigurationProperties(prefix = "shibui.pac4j") @EnableConfigurationProperties @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") +@Getter +@Setter public class Pac4jConfigurationProperties { - final static String DEFAULT_AUTH_HEADER = "REMOTE_USER"; - private String keystorePath = "/tmp/samlKeystore.jks"; - private String keystorePassword = "changeit"; - private String privateKeyPassword = "changeit"; + final static String DEFAULT_AUTH_HEADER = "REMOTE_USER"; + private String authenticationHeader = DEFAULT_AUTH_HEADER; + private String callbackUrl; + private boolean forceServiceProviderMetadataGeneration = false; private String identityProviderMetadataPath = "/tmp/idp-metadata.xml"; + private String keystorePassword = "changeit"; + private String keystorePath = "/tmp/samlKeystore.jks"; private int maximumAuthenticationLifetime = 3600; + private String privateKeyPassword = "changeit"; + private SAML2ProfileMapping saml2ProfileMapping; private String serviceProviderEntityId = "https://unicon.net/shibui"; private String serviceProviderMetadataPath = "/tmp/sp-metadata.xml"; - private boolean forceServiceProviderMetadataGeneration = false; - private String callbackUrl; - private boolean wantAssertionsSigned = true; - private SAML2ProfileMapping saml2ProfileMapping; private String typeOfAuth = "SAML2"; - private String authenticationHeader = DEFAULT_AUTH_HEADER; + private boolean wantAssertionsSigned = true; + + @Getter + @Setter public static class SAML2ProfileMapping { - private String username; private String email; private String firstName; private String lastName; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - } - - public String getKeystorePath() { - return keystorePath; - } - - public void setKeystorePath(String keystorePath) { - this.keystorePath = keystorePath; - } - - public String getKeystorePassword() { - return keystorePassword; - } - - public void setKeystorePassword(String keystorePassword) { - this.keystorePassword = keystorePassword; - } - - public String getPrivateKeyPassword() { - return privateKeyPassword; - } - - public void setPrivateKeyPassword(String privateKeyPassword) { - this.privateKeyPassword = privateKeyPassword; - } - - public String getIdentityProviderMetadataPath() { - return identityProviderMetadataPath; - } - - public void setIdentityProviderMetadataPath(String identityProviderMetadataPath) { - this.identityProviderMetadataPath = identityProviderMetadataPath; - } - - public int getMaximumAuthenticationLifetime() { - return maximumAuthenticationLifetime; - } - - public void setMaximumAuthenticationLifetime(int maximumAuthenticationLifetime) { - this.maximumAuthenticationLifetime = maximumAuthenticationLifetime; - } - - public String getServiceProviderEntityId() { - return serviceProviderEntityId; - } - - public void setServiceProviderEntityId(String serviceProviderEntityId) { - this.serviceProviderEntityId = serviceProviderEntityId; - } - - public String getServiceProviderMetadataPath() { - return serviceProviderMetadataPath; - } - - public void setServiceProviderMetadataPath(String serviceProviderMetadataPath) { - this.serviceProviderMetadataPath = serviceProviderMetadataPath; - } - - public boolean isForceServiceProviderMetadataGeneration() { - return forceServiceProviderMetadataGeneration; - } - - public void setForceServiceProviderMetadataGeneration(boolean forceServiceProviderMetadataGeneration) { - this.forceServiceProviderMetadataGeneration = forceServiceProviderMetadataGeneration; - } - - public String getCallbackUrl() { - return callbackUrl; - } - - public void setCallbackUrl(String callbackUrl) { - this.callbackUrl = callbackUrl; - } - - public boolean isWantAssertionsSigned() { - return wantAssertionsSigned; - } - - public void setWantAssertionsSigned(boolean wantAssertionsSigned) { - this.wantAssertionsSigned = wantAssertionsSigned; - } - - public SAML2ProfileMapping getSaml2ProfileMapping() { - return saml2ProfileMapping; - } - - public void setSaml2ProfileMapping(SAML2ProfileMapping saml2ProfileMapping) { - this.saml2ProfileMapping = saml2ProfileMapping; - } - - public String getTypeOfAuth() { - return typeOfAuth; - } - - public void setTypeOfAuth(String typeOfAuth) { - this.typeOfAuth = typeOfAuth; - } - - public String getAuthenticationHeader() { - return authenticationHeader; - } - - public void setAuthenticationHeader(String authenticationHeader) { - this.authenticationHeader = authenticationHeader; - } + private String username; + } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index fc8532196..d42206e3f 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -26,14 +26,13 @@ import java.util.Optional; +import javax.servlet.Filter; + @Configuration @AutoConfigureOrder(-1) @ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") @AutoConfigureAfter(EmailConfiguration.class) -public class WebSecurity { - @Value("${shibui.logout-url:/dashboard}") - private static String logoutUrl; - +public class WebSecurity { @Bean("webSecurityConfig") public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(final Config config, UserRepository userRepository, RoleRepository roleRepository, Optional emailService, @@ -61,26 +60,29 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository use @Override protected void configure(HttpSecurity http) throws Exception { - final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, Pac4jConfiguration.PAC4J_CLIENT_NAME); - securityFilterForHeader.setMatchers("exclude-paths-matcher"); - - final CallbackFilter callbackFilter = new CallbackFilter(this.config); - - http.antMatcher("/**").addFilterBefore(callbackFilter, BasicAuthenticationFilter.class) - .addFilterBefore(securityFilterForHeader, BasicAuthenticationFilter.class) - .addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, - emailService), SecurityFilter.class); + http.antMatcher("/**"); + http.addFilterBefore(getFilter(config, pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class); + http.addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); http.authorizeRequests().anyRequest().fullyAuthenticated(); - - http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> response.sendRedirect("/unsecured/error.html")) - .and().formLogin().and().httpBasic().and() - .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl(StringUtils.isAllEmpty(logoutUrl) ? "/dashboard" : logoutUrl); - + http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> response.sendRedirect("/unsecured/error.html")); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); http.csrf().disable(); http.headers().frameOptions().disable(); } + private Filter getFilter(Config config2, String typeOfAuth) { + switch (typeOfAuth) { + case "SAML2": + return new CallbackFilter(this.config); + case "HEADER": + final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, + Pac4jConfiguration.PAC4J_CLIENT_NAME); + securityFilterForHeader.setMatchers("exclude-paths-matcher"); + return securityFilterForHeader; + } + return null; // This will cause a runtime error + } + @Override public void configure(org.springframework.security.config.annotation.web.builders.WebSecurity web) throws Exception { super.configure(web); From 2ef26b24559d5a4878162cbe570a68dd61427b13 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 13 Jul 2021 17:33:02 -0700 Subject: [PATCH 14/18] SHIBUI-1994 Bug fix and additional corrections --- .../ui/security/service/UserService.java | 9 +++++ .../unicon/shibui/pac4j/AddNewUserFilter.java | 12 ++++++- .../shibui/pac4j/Pac4jConfiguration.java | 34 ++++++++++++++----- .../net/unicon/shibui/pac4j/WebSecurity.java | 24 +++++++++---- ui/public/unsecured/error.html | 2 +- 5 files changed, 65 insertions(+), 16 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java index 3adca2b75..a2d11a1ab 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java @@ -61,4 +61,13 @@ public User getCurrentUser() { } return user; } + + public Set getUserRoles(String username) { + Optional user = userRepository.findByUsername(username); + HashSet result = new HashSet<>(); + if (user.isPresent() ) { + user.get().getRoles().forEach(role -> result.add(role.getName())); + } + return result; + } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java index aca51e6fc..f61b94aea 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java @@ -9,6 +9,9 @@ import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; import org.apache.commons.lang3.RandomStringUtils; +import org.pac4j.core.context.JEEContext; +import org.pac4j.core.context.session.JEESessionStore; +import org.pac4j.core.matching.matcher.Matcher; import org.pac4j.core.profile.CommonProfile; import org.pac4j.saml.profile.SAML2Profile; import org.slf4j.Logger; @@ -24,6 +27,7 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @@ -40,12 +44,14 @@ public class AddNewUserFilter implements Filter { private RoleRepository roleRepository; private Pac4jConfigurationProperties.SAML2ProfileMapping saml2ProfileMapping; private UserRepository userRepository; + private Matcher matcher; - public AddNewUserFilter(Pac4jConfigurationProperties pac4jConfigurationProperties, UserRepository userRepository, RoleRepository roleRepository, Optional emailService) { + public AddNewUserFilter(Pac4jConfigurationProperties pac4jConfigurationProperties, UserRepository userRepository, RoleRepository roleRepository, Matcher matcher, Optional emailService) { this.userRepository = userRepository; this.roleRepository = roleRepository; this.emailService = emailService; this.pac4jConfigurationProperties = pac4jConfigurationProperties; + this.matcher = matcher; saml2ProfileMapping = this.pac4jConfigurationProperties.getSaml2ProfileMapping(); } @@ -73,6 +79,10 @@ public void destroy() { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + JEEContext context = new JEEContext((HttpServletRequest)request, (HttpServletResponse)response); + if (!matcher.matches(context, JEESessionStore.INSTANCE)) { + return; + } Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null) { CommonProfile profile = (CommonProfile) authentication.getPrincipal(); diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index ac3f159c2..b73d7593d 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -16,15 +16,20 @@ import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.config.SAML2Configuration; import org.pac4j.saml.credentials.authenticator.SAML2Authenticator; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.server.ErrorPageRegistrar; +import org.springframework.boot.web.server.ErrorPageRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; import com.google.common.collect.Lists; import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; - +import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; import lombok.extern.slf4j.Slf4j; /** @@ -38,6 +43,9 @@ public class Pac4jConfiguration { public final static String PAC4J_CLIENT_NAME = "shibUIAuthClient"; + @Autowired + private UserService userService; + /** * Custom class that ensures we add the user's roles to the information when doing SAML2 auth */ @@ -52,6 +60,11 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps, log.info("**** Configuring PAC4J "); final Config config = new Config(); final Clients clients = new Clients(pac4jConfigProps.getCallbackUrl()); + + // configure the matcher for bypassing auth checks + PathMatcher pm = new PathMatcher(); + pm.setExcludedPaths(Lists.newArrayList("/favicon.ico", "/unsecured/**/*", "/assets/**/*.png", "/static/**/*")); + config.addMatcher("exclude-paths-matcher", pm); // Configure the client switch (pac4jConfigProps.getTypeOfAuth()) { @@ -99,20 +112,25 @@ public void validate(Credentials credentials, WebContext context, SessionStore s final CommonProfile profile = new CommonProfile(); String token = ((TokenCredentials)credentials).getToken(); profile.setId(token); + profile.setRoles(userService.getUserRoles(token)); credentials.setUserProfile(profile); } }); headerClient.setName(PAC4J_CLIENT_NAME); clients.setClients(headerClient); } - } - - // configure the matcher for bypassing auth checks - PathMatcher pm = new PathMatcher(); - pm.setExcludedPaths(Lists.newArrayList("/favicon.ico", "/unsecured/**/*", "/error", "/login", "/")); - config.addMatcher("exclude-paths-matcher", pm); - + } config.setClients(clients); return config; } + + @Bean + public ErrorPageRegistrar errorPageRegistrar() { + return this::registerErrorPages; + } + + private void registerErrorPages(ErrorPageRegistry registry) { + registry.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/unsecured/error.html")); + registry.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN, "/unsecured/error.html")); + } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java index d42206e3f..b16af86ba 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/WebSecurity.java @@ -7,6 +7,8 @@ import org.apache.commons.lang3.StringUtils; import org.pac4j.core.config.Config; +import org.pac4j.core.matching.matcher.Matcher; +import org.pac4j.core.matching.matcher.PathMatcher; import org.pac4j.springframework.security.web.CallbackFilter; import org.pac4j.springframework.security.web.SecurityFilter; import org.springframework.beans.factory.annotation.Value; @@ -60,23 +62,30 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserRepository use @Override protected void configure(HttpSecurity http) throws Exception { - http.antMatcher("/**"); - http.addFilterBefore(getFilter(config, pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class); - http.addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, emailService), SecurityFilter.class); - http.authorizeRequests().anyRequest().fullyAuthenticated(); + http.authorizeRequests().antMatchers("/unsecured/**/*").permitAll(); + + // add filter based on auth type + http.antMatcher("/**").addFilterBefore(getFilter(config, pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class); + + // add the new user filter + http.addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, getPathMatcher("exclude-paths-matcher") , emailService), SecurityFilter.class); + http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> response.sendRedirect("/unsecured/error.html")); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); http.csrf().disable(); http.headers().frameOptions().disable(); } + private Matcher getPathMatcher(String name) { + return config.getMatchers().get(name); + } + private Filter getFilter(Config config2, String typeOfAuth) { switch (typeOfAuth) { case "SAML2": return new CallbackFilter(this.config); case "HEADER": - final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, - Pac4jConfiguration.PAC4J_CLIENT_NAME); + final SecurityFilter securityFilterForHeader = new SecurityFilter(this.config, Pac4jConfiguration.PAC4J_CLIENT_NAME); securityFilterForHeader.setMatchers("exclude-paths-matcher"); return securityFilterForHeader; } @@ -91,6 +100,9 @@ public void configure(org.springframework.security.config.annotation.web.builder firewall.setAllowUrlEncodedSlash(true); firewall.setAllowUrlEncodedDoubleSlash(true); web.httpFirewall(firewall); + + // These don't need to be secured + web.ignoring().antMatchers("/favicon.ico", "/unsecured/**/*", "/assets/**/*.png", "/static/**/*", "/**/*.css"); } } diff --git a/ui/public/unsecured/error.html b/ui/public/unsecured/error.html index 5535dc452..4d200efa8 100644 --- a/ui/public/unsecured/error.html +++ b/ui/public/unsecured/error.html @@ -6,7 +6,7 @@ - + From e7f10d1e18e07b6241e2a729b7d6bf35112af37d Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 13 Jul 2021 21:08:48 -0700 Subject: [PATCH 15/18] SHIBUI-1994 Fix for new users --- .../net/unicon/shibui/pac4j/AddNewUserFilter.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java index f61b94aea..06195db23 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java @@ -29,6 +29,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.transaction.Transactional; + import java.io.IOException; import java.util.List; import java.util.Optional; @@ -55,12 +57,18 @@ public AddNewUserFilter(Pac4jConfigurationProperties pac4jConfigurationPropertie saml2ProfileMapping = this.pac4jConfigurationProperties.getSaml2ProfileMapping(); } + @Transactional private User buildAndPersistNewUserFromProfile(CommonProfile profile) { - Role noRole = roleRepository.findByName(ROLE_NONE).orElse(new Role(ROLE_NONE)); - roleRepository.save(noRole); + Optional noRole = roleRepository.findByName(ROLE_NONE); + Role newUserRole; + if (noRole.isEmpty()) { + newUserRole = new Role(ROLE_NONE); + newUserRole = roleRepository.save(newUserRole); + } + newUserRole = noRole.get(); User user = new User(); - user.getRoles().add(noRole); + user.getRoles().add(newUserRole); user.setUsername(getAttributeFromProfile(profile, "username")); user.setPassword(BCrypt.hashpw(RandomStringUtils.randomAlphanumeric(20), BCrypt.gensalt())); user.setFirstName(getAttributeFromProfile(profile, "firstName")); From 8896350cb4cf035719d56e665e0e35ae5b57ba51 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 13 Jul 2021 22:10:24 -0700 Subject: [PATCH 16/18] SHIBUI-1774 fixing tests --- .../net/unicon/shibui/pac4j/Pac4jAuditorAware.java | 2 ++ .../unicon/shibui/pac4j/AddNewUserFilterTests.groovy | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jAuditorAware.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jAuditorAware.java index 47332d43b..81f573fe1 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jAuditorAware.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jAuditorAware.java @@ -1,11 +1,13 @@ package net.unicon.shibui.pac4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.domain.AuditorAware; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import java.util.Optional; +@ConditionalOnProperty(name = "shibui.pac4j-enabled", havingValue = "true") public class Pac4jAuditorAware implements AuditorAware { private static final String ANONYMOUS = "anonymousUser"; diff --git a/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy b/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy index 6c44f5699..6a1c7e976 100644 --- a/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy +++ b/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy @@ -5,6 +5,9 @@ import edu.internet2.tier.shibboleth.admin.ui.security.model.User import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository import edu.internet2.tier.shibboleth.admin.ui.service.EmailService + +import org.pac4j.core.matching.matcher.PathMatcher +import org.pac4j.core.profile.CommonProfile import org.pac4j.saml.profile.SAML2Profile import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.EnableConfigurationProperties @@ -17,6 +20,7 @@ import spock.lang.Subject import javax.servlet.FilterChain import javax.servlet.ServletRequest +import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse /** @@ -30,7 +34,7 @@ class AddNewUserFilterTests extends Specification { RoleRepository roleRepository = Mock() EmailService emailService = Mock() - ServletRequest request = Mock() + HttpServletRequest request = Mock() HttpServletResponse response = Mock() FilterChain chain = Mock() @@ -51,7 +55,7 @@ class AddNewUserFilterTests extends Specification { securityContext.getAuthentication() >> authentication authentication.getPrincipal() >> saml2Profile - addNewUserFilter = new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, Optional.of(emailService)) + addNewUserFilter = new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, new PathMatcher(), Optional.of(emailService)) saml2ProfileMapping = pac4jConfigurationProperties.saml2ProfileMapping } @@ -70,7 +74,7 @@ class AddNewUserFilterTests extends Specification { addNewUserFilter.doFilter(request, response, chain) then: - 1 * roleRepository.save(_) + 0 * roleRepository.save(_) 1 * userRepository.save(_ as User) >> { User user -> user } 1 * emailService.sendNewUserMail('newUser') 1 * response.sendRedirect("/unsecured/error.html") From 08390a2d342dcf592116f4c2a608d45548ea5f61 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 20 Jul 2021 15:41:43 -0500 Subject: [PATCH 17/18] [SHIBUI-1774] update for proper reverse proxy configuration --- pac4j-module/src/test/docker/conf-header/application.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pac4j-module/src/test/docker/conf-header/application.yml b/pac4j-module/src/test/docker/conf-header/application.yml index 252f055e2..0534c57f8 100644 --- a/pac4j-module/src/test/docker/conf-header/application.yml +++ b/pac4j-module/src/test/docker/conf-header/application.yml @@ -10,3 +10,6 @@ logging: level: org.pac4j: "TRACE" org.opensaml: "INFO" +server.tomcat: + remote-ip-header: x-forwarded-for + protocol-header: x-forwarded-proto From 98131766ba3857e849397d154754ceb43a908141 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Fri, 23 Jul 2021 12:16:33 -0700 Subject: [PATCH 18/18] SHIBUI-1774 Changes from feedback --- pac4j-module/build.gradle | 3 +- .../unicon/shibui/pac4j/AddNewUserFilter.java | 46 ++++--------------- .../shibui/pac4j/BetterSAML2Profile.java | 28 +++++++++-- ...calUserProfileAuthorizationGenerator.java} | 14 +++--- .../shibui/pac4j/Pac4jConfiguration.java | 11 +++-- .../pac4j/Pac4jConfigurationProperties.java | 4 +- .../src/main/resources/application.yml | 2 +- .../src/test/docker/conf/application.yml | 2 +- .../shibui/pac4j/AddNewUserFilterTests.groovy | 9 ++-- 9 files changed, 55 insertions(+), 64 deletions(-) rename pac4j-module/src/main/java/net/unicon/shibui/pac4j/{SAML2ModelAuthorizationGenerator.java => LocalUserProfileAuthorizationGenerator.java} (73%) diff --git a/pac4j-module/build.gradle b/pac4j-module/build.gradle index 4318595df..a84d2fe11 100644 --- a/pac4j-module/build.gradle +++ b/pac4j-module/build.gradle @@ -28,7 +28,8 @@ generateLombokConfig.enabled = false dependencies { compileOnly project(':backend') - compile "org.pac4j:spring-security-pac4j:6.0.0" // pac4j is "off" - spring 6.0.0 here uses 5.1 core, thus differences in versions + compile "org.pac4j:spring-security-pac4j:6.0.0" // pac4j is "off" - spring 6.0.0 here uses 5.1 core, thus differences in versions + compile "org.pac4j:pac4j-core:5.1.0" compile "org.pac4j:pac4j-http:5.1.0" compile "org.pac4j:pac4j-saml:5.1.0", { // opensaml libraries are provided diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java index 06195db23..c379690c5 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/AddNewUserFilter.java @@ -44,7 +44,7 @@ public class AddNewUserFilter implements Filter { private Optional emailService; private Pac4jConfigurationProperties pac4jConfigurationProperties; private RoleRepository roleRepository; - private Pac4jConfigurationProperties.SAML2ProfileMapping saml2ProfileMapping; + private Pac4jConfigurationProperties.SimpleProfileMapping simpleProfileMapping; private UserRepository userRepository; private Matcher matcher; @@ -54,7 +54,7 @@ public AddNewUserFilter(Pac4jConfigurationProperties pac4jConfigurationPropertie this.emailService = emailService; this.pac4jConfigurationProperties = pac4jConfigurationProperties; this.matcher = matcher; - saml2ProfileMapping = this.pac4jConfigurationProperties.getSaml2ProfileMapping(); + simpleProfileMapping = this.pac4jConfigurationProperties.getSimpleProfileMapping(); } @Transactional @@ -69,11 +69,11 @@ private User buildAndPersistNewUserFromProfile(CommonProfile profile) { User user = new User(); user.getRoles().add(newUserRole); - user.setUsername(getAttributeFromProfile(profile, "username")); + user.setUsername(profile.getUsername()); user.setPassword(BCrypt.hashpw(RandomStringUtils.randomAlphanumeric(20), BCrypt.gensalt())); - user.setFirstName(getAttributeFromProfile(profile, "firstName")); - user.setLastName(getAttributeFromProfile(profile, "lastName")); - user.setEmailAddress(getAttributeFromProfile(profile, "email")); + user.setFirstName(profile.getFirstName()); + user.setLastName(profile.getFamilyName()); + user.setEmailAddress(profile.getEmail()); User persistedUser = userRepository.save(user); if (log.isDebugEnabled()) { log.debug("Persisted new user:\n" + user); @@ -95,11 +95,11 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha if (authentication != null) { CommonProfile profile = (CommonProfile) authentication.getPrincipal(); if (profile != null) { - String username = getAttributeFromProfile(profile, "username"); + String username = profile.getUsername(); if (username != null) { Optional persistedUser = userRepository.findByUsername(username); User user; - if (!persistedUser.isPresent()) { + if (persistedUser.isEmpty()) { user = buildAndPersistNewUserFromProfile(profile); emailService.ifPresent(e -> { try { @@ -122,36 +122,6 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } } - private String getAttributeFromProfile(CommonProfile profile, String stringKey) { - if (profile instanceof SAML2Profile) { - return getAttributeFromSAML2Profile(profile, stringKey); - } - return stringKey.equalsIgnoreCase("username") ? profile.getId() : null; - } - - @SuppressWarnings("unchecked") - private String getAttributeFromSAML2Profile(CommonProfile profile, String stringKey) { - String attributeKey = null; - switch (stringKey) { - case "username": - attributeKey = saml2ProfileMapping.getUsername(); - break; - case "firstName": - attributeKey = saml2ProfileMapping.getFirstName(); - break; - case "lastName": - attributeKey = saml2ProfileMapping.getLastName(); - break; - case "email": - attributeKey = saml2ProfileMapping.getEmail(); - break; - default: - // do we care? Not yet. - } - List attributeList = (List) profile.getAttribute(attributeKey); - return attributeList.size() < 1 ? null : attributeList.get(0); - } - @Override public void init(FilterConfig filterConfig) throws ServletException { } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/BetterSAML2Profile.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/BetterSAML2Profile.java index 58d16a9ec..17a5edd64 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/BetterSAML2Profile.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/BetterSAML2Profile.java @@ -2,22 +2,40 @@ import org.pac4j.saml.profile.SAML2Profile; +import net.unicon.shibui.pac4j.Pac4jConfigurationProperties.SimpleProfileMapping; + import java.util.Collection; public class BetterSAML2Profile extends SAML2Profile { - private final String usernameAttribute; + private SimpleProfileMapping profileMapping; + + public BetterSAML2Profile(final SimpleProfileMapping simpleProfileMapping) { + this.profileMapping = simpleProfileMapping; + } - public BetterSAML2Profile(final String usernameAttribute) { - this.usernameAttribute = usernameAttribute; + @Override + public String getEmail() { + return (String) getAttribute(profileMapping.getEmail()); + } + + @Override + public String getFamilyName() { + return (String) getAttribute(profileMapping.getLastName()); + } + + @Override + public String getFirstName() { + return (String) getAttribute(profileMapping.getFirstName()); } @Override public String getUsername() { - Object username = getAttribute(usernameAttribute); + Object username = getAttribute(profileMapping.getUsername()); if (username instanceof Collection) { - return (String) ((Collection)username).toArray()[0]; + return (String) ((Collection) username).toArray()[0]; } else { return (String) username; } } + } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/LocalUserProfileAuthorizationGenerator.java similarity index 73% rename from pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java rename to pac4j-module/src/main/java/net/unicon/shibui/pac4j/LocalUserProfileAuthorizationGenerator.java index 4286d4e38..1f0f0cba1 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/SAML2ModelAuthorizationGenerator.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/LocalUserProfileAuthorizationGenerator.java @@ -1,26 +1,26 @@ package net.unicon.shibui.pac4j; -import edu.internet2.tier.shibboleth.admin.ui.security.model.User; -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; +import java.util.Optional; + import org.pac4j.core.authorization.generator.AuthorizationGenerator; import org.pac4j.core.context.WebContext; import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.profile.UserProfile; -import org.pac4j.saml.profile.SAML2Profile; -import java.util.Optional; +import edu.internet2.tier.shibboleth.admin.ui.security.model.User; +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; -public class SAML2ModelAuthorizationGenerator implements AuthorizationGenerator { +public class LocalUserProfileAuthorizationGenerator implements AuthorizationGenerator { private final UserRepository userRepository; - public SAML2ModelAuthorizationGenerator(UserRepository userRepository) { + public LocalUserProfileAuthorizationGenerator(UserRepository userRepository) { this.userRepository = userRepository; } @Override public Optional generate(WebContext context, SessionStore sessionStore, UserProfile profile) { Optional user = userRepository.findByUsername(profile.getUsername()); - user.ifPresent( u -> ((SAML2Profile)profile).addRole(u.getRole())); + user.ifPresent( u -> profile.addRole(u.getRole()) ); return Optional.of(profile); } } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java index b73d7593d..5e173f151 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfiguration.java @@ -50,13 +50,13 @@ public class Pac4jConfiguration { * Custom class that ensures we add the user's roles to the information when doing SAML2 auth */ @Bean - public SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator(UserRepository userRepository) { - return new SAML2ModelAuthorizationGenerator(userRepository); + public LocalUserProfileAuthorizationGenerator saml2ModelAuthorizationGenerator(UserRepository userRepository) { + return new LocalUserProfileAuthorizationGenerator(userRepository); } @Bean(name = "pac4j-config") public Config config(final Pac4jConfigurationProperties pac4jConfigProps, - final SAML2ModelAuthorizationGenerator saml2ModelAuthorizationGenerator) { + final LocalUserProfileAuthorizationGenerator saml2ModelAuthorizationGenerator) { log.info("**** Configuring PAC4J "); final Config config = new Config(); final Clients clients = new Clients(pac4jConfigProps.getCallbackUrl()); @@ -80,7 +80,7 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps, saml2Config.setServiceProviderMetadataPath(pac4jConfigProps.getServiceProviderMetadataPath()); saml2Config.setForceServiceProviderMetadataGeneration(pac4jConfigProps.isForceServiceProviderMetadataGeneration()); saml2Config.setWantsAssertionsSigned(pac4jConfigProps.isWantAssertionsSigned()); - saml2Config.setAttributeAsId(pac4jConfigProps.getSaml2ProfileMapping().getUsername()); + saml2Config.setAttributeAsId(pac4jConfigProps.getSimpleProfileMapping().getUsername()); //saml2Config.setPostLogoutURL(pac4jConfigProps.getPostLogoutURL()); // consideration needed? //saml2Config.setSpLogoutRequestBindingType(pac4jConfigProps.getSpLogoutRequestBindingType()); @@ -88,7 +88,7 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps, saml2Client.setName("Saml2Client"); saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator); SAML2Authenticator saml2Authenticator = new SAML2Authenticator(saml2Config.getAttributeAsId(), saml2Config.getMappedAttributes()); - saml2Authenticator.setProfileDefinition(new CommonProfileDefinition(p -> new BetterSAML2Profile(pac4jConfigProps.getSaml2ProfileMapping().getUsername()))); + saml2Authenticator.setProfileDefinition(new CommonProfileDefinition(p -> new BetterSAML2Profile(pac4jConfigProps.getSimpleProfileMapping()))); saml2Client.setAuthenticator(saml2Authenticator); saml2Client.setName(PAC4J_CLIENT_NAME); @@ -112,6 +112,7 @@ public void validate(Credentials credentials, WebContext context, SessionStore s final CommonProfile profile = new CommonProfile(); String token = ((TokenCredentials)credentials).getToken(); profile.setId(token); + profile.addAttribute("username", token); profile.setRoles(userService.getUserRoles(token)); credentials.setUserProfile(profile); } diff --git a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java index 8a44baf47..977164958 100644 --- a/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java +++ b/pac4j-module/src/main/java/net/unicon/shibui/pac4j/Pac4jConfigurationProperties.java @@ -28,7 +28,7 @@ public class Pac4jConfigurationProperties { private String keystorePath = "/tmp/samlKeystore.jks"; private int maximumAuthenticationLifetime = 3600; private String privateKeyPassword = "changeit"; - private SAML2ProfileMapping saml2ProfileMapping; + private SimpleProfileMapping simpleProfileMapping; private String serviceProviderEntityId = "https://unicon.net/shibui"; private String serviceProviderMetadataPath = "/tmp/sp-metadata.xml"; private String typeOfAuth = "SAML2"; @@ -37,7 +37,7 @@ public class Pac4jConfigurationProperties { @Getter @Setter - public static class SAML2ProfileMapping { + public static class SimpleProfileMapping { private String email; private String firstName; private String lastName; diff --git a/pac4j-module/src/main/resources/application.yml b/pac4j-module/src/main/resources/application.yml index 4042fd939..ebba4fcd9 100644 --- a/pac4j-module/src/main/resources/application.yml +++ b/pac4j-module/src/main/resources/application.yml @@ -1,6 +1,6 @@ shibui: pac4j: - saml2ProfileMapping: + simpleProfileMapping: username: urn:oid:0.9.2342.19200300.100.1.3 firstName: givenName lastName: sn diff --git a/pac4j-module/src/test/docker/conf/application.yml b/pac4j-module/src/test/docker/conf/application.yml index 90ddce36a..b49782897 100644 --- a/pac4j-module/src/test/docker/conf/application.yml +++ b/pac4j-module/src/test/docker/conf/application.yml @@ -31,7 +31,7 @@ shibui: forceServiceProviderMetadataGeneration: true callbackUrl: "https://localhost:8443/callback" maximumAuthenticationLifetime: 3600000 - saml2ProfileMapping: + simpleProfileMapping: username: urn:oid:0.9.2342.19200300.100.1.1 firstName: urn:oid:2.5.4.42 lastName: urn:oid:2.5.4.4 diff --git a/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy b/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy index 6a1c7e976..d15b70f0a 100644 --- a/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy +++ b/pac4j-module/src/test/groovy/net/unicon/shibui/pac4j/AddNewUserFilterTests.groovy @@ -45,7 +45,7 @@ class AddNewUserFilterTests extends Specification { @Autowired Pac4jConfigurationProperties pac4jConfigurationProperties - Pac4jConfigurationProperties.SAML2ProfileMapping saml2ProfileMapping + Pac4jConfigurationProperties.SimpleProfileMapping profileMapping @Subject AddNewUserFilter addNewUserFilter @@ -56,7 +56,7 @@ class AddNewUserFilterTests extends Specification { authentication.getPrincipal() >> saml2Profile addNewUserFilter = new AddNewUserFilter(pac4jConfigurationProperties, userRepository, roleRepository, new PathMatcher(), Optional.of(emailService)) - saml2ProfileMapping = pac4jConfigurationProperties.saml2ProfileMapping + profileMapping = pac4jConfigurationProperties.simpleProfileMapping } def "new users are redirected"() { @@ -65,8 +65,9 @@ class AddNewUserFilterTests extends Specification { 'FirstName': 'New', 'LastName': 'User', 'Email': 'newuser@institution.edu'].each { key, value -> - saml2Profile.getAttribute(saml2ProfileMapping."get${key}"()) >> [value] + saml2Profile.getAttribute(profileMapping."get${key}"()) >> [value] } + saml2Profile.getUsername() >> "newUser" userRepository.findByUsername('newUser') >> Optional.empty() roleRepository.findByName('ROLE_NONE') >> Optional.of(new Role('ROLE_NONE')) @@ -82,7 +83,7 @@ class AddNewUserFilterTests extends Specification { def "existing users are not redirected"() { given: - saml2Profile.getAttribute(saml2ProfileMapping.getUsername()) >> ['existingUser'] + saml2Profile.getUsername() >> "existingUser" userRepository.findByUsername('existingUser') >> Optional.of(new User().with { it.username = 'existingUser' it.roles = [new Role('ROLE_USER')]