Compare commits
11 commits
Author | SHA1 | Date | |
---|---|---|---|
|
861f3487cd | ||
|
1165cf6189 | ||
|
bd19e88364 | ||
|
e4c88cdcf6 | ||
|
de26a35223 | ||
|
644a4221ec | ||
|
4355ed1729 | ||
|
7c929ac251 | ||
|
db1407912c | ||
|
21569ae1a2 | ||
|
ea2f4f1c14 |
35 changed files with 625 additions and 455 deletions
|
@ -46,6 +46,12 @@
|
|||
<property name="fileExtensions" value="jsp,java"/>
|
||||
</module>
|
||||
|
||||
<module name="LineLength">
|
||||
<property name="max" value="180" />
|
||||
<property name="ignorePattern" value="@version|@see|@todo|TODO"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for Headers -->
|
||||
<!-- See http://checkstyle.sf.net/config_header.html -->
|
||||
<!--
|
||||
|
@ -80,11 +86,6 @@
|
|||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="LineLength">
|
||||
<property name="max" value="180" />
|
||||
<property name="ignorePattern" value="@version|@see|@todo|TODO"/>
|
||||
</module>
|
||||
|
||||
<module name="EmptyBlock">
|
||||
<property name="option" value="TEXT"/>
|
||||
<property name="tokens" value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
||||
|
|
|
@ -31,4 +31,7 @@
|
|||
<!-- due to bug with java 11 -->
|
||||
<Bug pattern="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"/>
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug pattern="DMI_RANDOM_USED_ONLY_ONCE"/>
|
||||
</Match>
|
||||
</FindBugsFilter>
|
|
@ -8,27 +8,28 @@
|
|||
"npm": ">=3.9"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --mode=production",
|
||||
"build": "webpack --mode=development",
|
||||
"clean": "rimraf dist/",
|
||||
"test": "karma start test/karma.conf.js",
|
||||
"test-single-run": "karma start test/karma.conf.js --singleRun --no-auto-watch",
|
||||
"start": "webpack-dev-server --mode=development --port 4000 --history-api-fallback --colors"
|
||||
"start": "webpack-dev-server --mode=development --port 4000 --history-api-fallback --colors --progress"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@microfocus/ias-icons": "1.0.1",
|
||||
"@microfocus/ng-ias": "1.0.0-alpha.2",
|
||||
"@microfocus/ux-ias": "1.0.0-rc",
|
||||
"@microfocus/ias-icons": "1.0.4",
|
||||
"@microfocus/ng-ias": "1.0.1",
|
||||
"@microfocus/ux-ias": "1.1.2",
|
||||
"@uirouter/angularjs": "1.0.15",
|
||||
"angular": "1.6.9",
|
||||
"angular-aria": "1.6.9",
|
||||
"angular-sanitize": "1.6.9",
|
||||
"angular-translate": "2.17.0",
|
||||
"angular": "^1.7.9",
|
||||
"angular-aria": "1.7.8",
|
||||
"angular-sanitize": "1.7.9",
|
||||
"angular-translate": "2.18.1",
|
||||
"core-js": "3.5.0",
|
||||
"textangular": "1.5.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/angular": "1.6.43",
|
||||
"@types/angular": "^1.8.1",
|
||||
"@types/angular-mocks": "1.5.11",
|
||||
"@types/angular-translate": "2.15.2",
|
||||
"@types/angular-ui-router": "1.1.40",
|
||||
|
@ -36,8 +37,8 @@
|
|||
"@types/node": "9.4.7",
|
||||
"angular-mocks": "1.6.9",
|
||||
"autoprefixer": "8.1.0",
|
||||
"copy-webpack-plugin": "4.5.1",
|
||||
"css-loader": "0.28.10",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^3.3.2",
|
||||
"file-loader": "1.1.11",
|
||||
"html-loader": "0.5.5",
|
||||
"html-webpack-plugin": "3.0.6",
|
||||
|
@ -45,10 +46,10 @@
|
|||
"imports-loader": "0.8.0",
|
||||
"jasmine": "3.2.0",
|
||||
"jasmine-core": "3.2.1",
|
||||
"jshint": "2.9.5",
|
||||
"jshint": "^2.13.0",
|
||||
"jshint-loader": "0.8.4",
|
||||
"json-loader": "0.5.7",
|
||||
"karma": "3.1.1",
|
||||
"karma": "^4.4.1",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-jasmine": "1.1.2",
|
||||
"karma-jasmine-html-reporter": "1.3.1",
|
||||
|
@ -58,7 +59,7 @@
|
|||
"karma-webpack": "3.0.5",
|
||||
"moment": "2.21.0",
|
||||
"ngtemplate-loader": "2.0.1",
|
||||
"node-sass": "4.7.2",
|
||||
"node-sass": "^6.0.1",
|
||||
"phantomjs": "2.1.7",
|
||||
"phantomjs-prebuilt": "2.1.16",
|
||||
"postcss-loader": "2.1.1",
|
||||
|
@ -67,6 +68,7 @@
|
|||
"sass-loader": "6.0.7",
|
||||
"string-replace-loader": "2.1.1",
|
||||
"style-loader": "0.20.3",
|
||||
"trim-newlines": ">=3.0.1",
|
||||
"ts-loader": "4.0.1",
|
||||
"ts-mockito": "2.3.1",
|
||||
"tslint": "5.9.1",
|
||||
|
@ -74,8 +76,8 @@
|
|||
"typescript": "2.7.2",
|
||||
"uglifyjs-webpack-plugin": "1.2.3",
|
||||
"url-loader": "1.0.1",
|
||||
"webpack": "4.1.1",
|
||||
"webpack-cli": "2.0.12",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-dev-server": "3.1.14",
|
||||
"webpack-merge": "4.1.2",
|
||||
"write-file-webpack-plugin": "4.2.0"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
|||
|
||||
<properties>
|
||||
<project.root.basedir>${project.basedir}/..</project.root.basedir>
|
||||
<node.version>v14.17.2</node.version>
|
||||
<npm.version>6.14.13</npm.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
|
@ -79,11 +81,11 @@
|
|||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>1.7.6</version>
|
||||
<version>1.12.0</version>
|
||||
<configuration>
|
||||
<nodeVersion>v8.9.4</nodeVersion>
|
||||
<npmVersion>5.6.0</npmVersion>
|
||||
<installDirectory>.node</installDirectory>
|
||||
<nodeVersion>${node.version}</nodeVersion>
|
||||
<npmVersion>${npm.version}</npmVersion>
|
||||
<installDirectory>${settings.localRepository}/frontend-maven-plugin/node-${node.version}</installDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -115,7 +117,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
|
|
|
@ -24,7 +24,7 @@ import 'angular-sanitize';
|
|||
import '@microfocus/ng-ias/dist/ng-ias';
|
||||
|
||||
// Add a polyfill for Set() for IE11, since it's used in peoplesearch-base.component.ts
|
||||
import 'core-js/es6/set';
|
||||
import 'core-js/es/set';
|
||||
|
||||
import { bootstrap, module } from 'angular';
|
||||
import helpDeskModule from './helpdesk.module';
|
||||
|
|
|
@ -23,7 +23,7 @@ import 'angular-translate';
|
|||
import '@microfocus/ng-ias/dist/ng-ias';
|
||||
|
||||
// Add a polyfill for Set() for IE11, since it's used in peoplesearch-base.component.ts
|
||||
import 'core-js/es6/set';
|
||||
import 'core-js/es/set';
|
||||
|
||||
import { bootstrap, module } from 'angular';
|
||||
import ConfigService from '../../services/peoplesearch-config.service';
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -122,17 +122,17 @@
|
|||
<dependency>
|
||||
<groupId>commons-net</groupId>
|
||||
<artifactId>commons-net</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.8.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.7</version>
|
||||
<version>1.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.9</version>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
|
@ -142,7 +142,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.9</version>
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
|
@ -157,12 +157,12 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
<version>2.8.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.xodus</groupId>
|
||||
<artifactId>xodus-environment</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.232</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
<plugin>
|
||||
<groupId>com.google.cloud.tools</groupId>
|
||||
<artifactId>jib-maven-plugin</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>3.1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-docker-image</id>
|
||||
|
@ -44,10 +44,12 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<skip>${skipDocker}</skip>
|
||||
<jib.console>plain</jib.console>
|
||||
<from>
|
||||
<image>adoptopenjdk/openjdk11:jre</image>
|
||||
</from>
|
||||
<outputPaths>
|
||||
<tar>target/pwm-docker-image-${project.version}.tar</tar>
|
||||
</outputPaths>
|
||||
<to>
|
||||
<image>${dockerImageTag}</image>
|
||||
</to>
|
||||
|
@ -55,14 +57,17 @@
|
|||
<entrypoint>
|
||||
<arg>/app/startup.sh</arg>
|
||||
</entrypoint>
|
||||
<format>docker</format>
|
||||
<ports>8443</ports>
|
||||
<ports>
|
||||
<port>8443</port>
|
||||
</ports>
|
||||
<volumes>
|
||||
<volume>/config</volume>
|
||||
</volumes>
|
||||
</container>
|
||||
<extraDirectory>
|
||||
<path>${project.basedir}/src/main/image-files</path>
|
||||
<extraDirectories>
|
||||
<paths>
|
||||
<path>${project.basedir}/src/main/image-files</path>
|
||||
</paths>
|
||||
<permissions>
|
||||
<permission>
|
||||
<file>/app/startup.sh</file>
|
||||
|
@ -73,7 +78,7 @@
|
|||
<mode>755</mode>
|
||||
</permission>
|
||||
</permissions>
|
||||
</extraDirectory>
|
||||
</extraDirectories>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
<properties>
|
||||
<project.root.basedir>${project.basedir}/..</project.root.basedir>
|
||||
<tomcat.version>9.0.21</tomcat.version>
|
||||
<tomcat.version>9.0.52</tomcat.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<!-- prevent normal jar from being built -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-jar</id>
|
||||
|
|
34
pom.xml
34
pom.xml
|
@ -4,7 +4,7 @@
|
|||
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>PWM Password Self Service</name>
|
||||
|
@ -167,12 +167,12 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.1.2</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>8.21</version>
|
||||
<version>8.45.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
|
@ -242,12 +242,12 @@
|
|||
<plugin>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-maven-plugin</artifactId>
|
||||
<version>3.1.11</version>
|
||||
<version>4.2.3</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs</artifactId>
|
||||
<version>4.0.0-beta2</version>
|
||||
<version>4.2.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
|
@ -268,7 +268,7 @@
|
|||
<plugin> <!-- checks owsp vulnerability database -->
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>5.0.0-M3</version>
|
||||
<version>6.2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
@ -276,6 +276,10 @@
|
|||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<yarnAuditAnalyzerEnabled>false</yarnAuditAnalyzerEnabled>
|
||||
<nodeAnalyzerEnabled>false</nodeAnalyzerEnabled>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
@ -285,13 +289,13 @@
|
|||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.8</version>
|
||||
<version>1.18.20</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
<version>4.0.0-beta2</version>
|
||||
<version>4.3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -299,43 +303,43 @@
|
|||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.28.2</version>
|
||||
<version>3.11.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.12.2</version>
|
||||
<version>3.20.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
<version>2.23.2</version>
|
||||
<version>2.27.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.11</version>
|
||||
<version>0.9.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>1.21</version>
|
||||
<version>1.33</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>1.21</version>
|
||||
<version>1.33</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
<version>2.8.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jdom</groupId>
|
||||
|
@ -45,14 +45,14 @@
|
|||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.62</version>
|
||||
<version>1.69</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
@ -72,7 +72,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
<version>2.8.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -105,7 +105,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
|
@ -192,22 +192,22 @@
|
|||
<dependency>
|
||||
<groupId>com.github.ldapchai</groupId>
|
||||
<artifactId>ldapchai</artifactId>
|
||||
<version>0.7.5</version>
|
||||
<version>0.8.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-net</groupId>
|
||||
<artifactId>commons-net</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>3.8.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>1.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.7</version>
|
||||
<version>1.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
|
@ -217,12 +217,12 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.9</version>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
<artifactId>commons-validator</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>1.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
|
@ -232,7 +232,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.9</version>
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graylog2</groupId>
|
||||
|
@ -247,7 +247,7 @@
|
|||
<dependency>
|
||||
<groupId>org.jasig.cas.client</groupId>
|
||||
<artifactId>cas-client-core</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.6.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.glxn</groupId>
|
||||
|
@ -257,12 +257,12 @@
|
|||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.62</version>
|
||||
<version>1.69</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.62</version>
|
||||
<version>1.69</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
|
@ -287,17 +287,17 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
<version>2.8.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.blueconic</groupId>
|
||||
<artifactId>browscap-java</artifactId>
|
||||
<version>1.2.9</version>
|
||||
<version>1.3.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.xodus</groupId>
|
||||
<artifactId>xodus-environment</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.232</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
@ -307,17 +307,17 @@
|
|||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>webjars-locator-core</artifactId>
|
||||
<version>0.37</version>
|
||||
<version>0.47</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
<version>2.7.0</version>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nulab-inc</groupId>
|
||||
<artifactId>zxcvbn</artifactId>
|
||||
<version>1.2.5</version>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ziplet</groupId>
|
||||
|
|
|
@ -217,6 +217,7 @@ public abstract class PwmConstants
|
|||
"Your password must be scanned by the TSA to ensure the safety of your fellow travelers. Please take off your password's shoes to continue.",
|
||||
"That password really tied the room together dude.",
|
||||
"Bite my shiny metal password!",
|
||||
"ben makes password software go woooo",
|
||||
|
||||
//nick helm
|
||||
"I needed a password eight characters long so I picked Snow White and the Seven Dwarves.",
|
||||
|
|
|
@ -39,24 +39,6 @@ public class CrChallengeItemBean implements Serializable, Challenge
|
|||
private int maxQuestionCharsInAnswer;
|
||||
private boolean enforceWordlist;
|
||||
|
||||
@Override
|
||||
public boolean isLocked()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChallengeText( final String challengeText )
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChallengeBean asChallengeBean()
|
||||
{
|
||||
|
|
|
@ -96,17 +96,6 @@ public class CrChallengePolicyBean implements Serializable, ChallengeSet
|
|||
return mininimumResponses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocked()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier()
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Collections;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PwmURL
|
||||
|
@ -48,7 +49,8 @@ public class PwmURL
|
|||
final String contextPath
|
||||
)
|
||||
{
|
||||
this.uri = uri;
|
||||
Objects.requireNonNull( uri );
|
||||
this.uri = uri.normalize();
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,58 +20,34 @@
|
|||
|
||||
package password.pwm.http.filter;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Value;
|
||||
import password.pwm.AppProperty;
|
||||
import password.pwm.Permission;
|
||||
import password.pwm.PwmApplication;
|
||||
import password.pwm.PwmApplicationMode;
|
||||
import password.pwm.PwmConstants;
|
||||
import password.pwm.bean.UserIdentity;
|
||||
import password.pwm.config.PwmSetting;
|
||||
import password.pwm.config.stored.ConfigurationProperty;
|
||||
import password.pwm.config.stored.ConfigurationReader;
|
||||
import password.pwm.config.stored.StoredConfiguration;
|
||||
import password.pwm.config.stored.StoredConfigurationImpl;
|
||||
import password.pwm.error.ErrorInformation;
|
||||
import password.pwm.error.PwmError;
|
||||
import password.pwm.error.PwmException;
|
||||
import password.pwm.error.PwmUnrecoverableException;
|
||||
import password.pwm.http.ContextManager;
|
||||
import password.pwm.http.JspUrl;
|
||||
import password.pwm.http.ProcessStatus;
|
||||
import password.pwm.http.PwmHttpResponseWrapper;
|
||||
import password.pwm.http.PwmRequest;
|
||||
import password.pwm.http.PwmRequestAttribute;
|
||||
import password.pwm.http.PwmSession;
|
||||
import password.pwm.http.PwmURL;
|
||||
import password.pwm.http.bean.ConfigManagerBean;
|
||||
import password.pwm.svc.intruder.RecordType;
|
||||
import password.pwm.http.servlet.PwmServletDefinition;
|
||||
import password.pwm.svc.sessiontrack.UserAgentUtils;
|
||||
import password.pwm.util.java.JavaHelper;
|
||||
import password.pwm.util.java.StringUtil;
|
||||
import password.pwm.util.java.TimeDuration;
|
||||
import password.pwm.util.logging.PwmLogger;
|
||||
import password.pwm.util.secure.PwmHashAlgorithm;
|
||||
import password.pwm.util.secure.SecureEngine;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigAccessFilter extends AbstractPwmFilter
|
||||
{
|
||||
private static final PwmLogger LOGGER = PwmLogger.forClass( ConfigAccessFilter.class );
|
||||
|
||||
private static final String COOKIE_NAME = PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN;
|
||||
private static final PwmHttpResponseWrapper.CookiePath COOKIE_PATH = PwmHttpResponseWrapper.CookiePath.Private;
|
||||
|
||||
@Override
|
||||
void processFilter( final PwmApplicationMode mode, final PwmRequest pwmRequest, final PwmFilterChain filterChain ) throws PwmException, IOException, ServletException
|
||||
void processFilter( final PwmApplicationMode mode, final PwmRequest pwmRequest, final PwmFilterChain filterChain )
|
||||
throws PwmException, IOException, ServletException
|
||||
{
|
||||
final PwmApplicationMode appMode = pwmRequest.getPwmApplication().getApplicationMode();
|
||||
if ( appMode == PwmApplicationMode.NEW )
|
||||
|
@ -111,17 +87,15 @@ public class ConfigAccessFilter extends AbstractPwmFilter
|
|||
@Override
|
||||
boolean isInterested( final PwmApplicationMode mode, final PwmURL pwmURL )
|
||||
{
|
||||
return pwmURL.isConfigManagerURL();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static ProcessStatus checkAuthentication(
|
||||
public static ProcessStatus checkAuthentication(
|
||||
final PwmRequest pwmRequest,
|
||||
final ConfigManagerBean configManagerBean
|
||||
)
|
||||
throws IOException, PwmUnrecoverableException, ServletException
|
||||
{
|
||||
final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
|
||||
final PwmSession pwmSession = pwmRequest.getPwmSession();
|
||||
final ConfigurationReader runningConfigReader = ContextManager.getContextManager( pwmRequest.getHttpServletRequest().getSession() ).getConfigReader();
|
||||
final StoredConfigurationImpl storedConfig = runningConfigReader.getStoredConfiguration();
|
||||
|
||||
|
@ -132,117 +106,15 @@ public class ConfigAccessFilter extends AbstractPwmFilter
|
|||
return ProcessStatus.Continue;
|
||||
}
|
||||
|
||||
final boolean persistentLoginEnabled = persistentLoginEnabled( pwmRequest );
|
||||
|
||||
if ( persistentLoginEnabled )
|
||||
if ( !pwmRequest.getURL().isPwmServletURL( PwmServletDefinition.ConfigManager_Login ) )
|
||||
{
|
||||
final boolean persistentLoginPassed = checkPersistentLoginCookie( pwmRequest, storedConfig );
|
||||
if ( persistentLoginPassed )
|
||||
{
|
||||
return processLoginSuccess( pwmRequest, persistentLoginEnabled );
|
||||
}
|
||||
configManagerBean.setPrePasswordEntryUrl( pwmRequest.getHttpServletRequest().getRequestURL().toString() );
|
||||
pwmRequest.sendRedirect( PwmServletDefinition.ConfigManager_Login );
|
||||
return ProcessStatus.Halt;
|
||||
}
|
||||
|
||||
final String password = pwmRequest.readParameterAsString( "password" );
|
||||
|
||||
boolean passwordAccepted = false;
|
||||
if ( !StringUtil.isEmpty( password ) )
|
||||
{
|
||||
if ( storedConfig.verifyPassword( password, pwmRequest.getConfig() ) )
|
||||
{
|
||||
passwordAccepted = true;
|
||||
LOGGER.trace( pwmRequest, () -> "valid configuration password accepted" );
|
||||
updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), true );
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.trace( pwmRequest, () -> "configuration password is not correct" );
|
||||
pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmSession );
|
||||
pwmApplication.getIntruderManager().mark( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME, pwmSession.getLabel() );
|
||||
final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_PASSWORD_ONLY_BAD );
|
||||
updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), false );
|
||||
return denyAndError( pwmRequest, errorInformation );
|
||||
}
|
||||
}
|
||||
|
||||
if ( passwordAccepted )
|
||||
{
|
||||
return processLoginSuccess( pwmRequest, persistentLoginEnabled );
|
||||
}
|
||||
|
||||
configManagerBean.setPrePasswordEntryUrl( pwmRequest.getHttpServletRequest().getRequestURL().toString() );
|
||||
|
||||
forwardToJsp( pwmRequest );
|
||||
return ProcessStatus.Halt;
|
||||
return ProcessStatus.Continue;
|
||||
}
|
||||
|
||||
private static void writePersistentLoginCookie( final PwmRequest pwmRequest )
|
||||
throws PwmUnrecoverableException
|
||||
{
|
||||
final int persistentSeconds = figureMaxLoginSeconds( pwmRequest );
|
||||
|
||||
if ( persistentSeconds > 0 )
|
||||
{
|
||||
final TimeDuration persistenceDuration = TimeDuration.of( persistentSeconds, TimeDuration.Unit.SECONDS );
|
||||
final Instant expirationDate = persistenceDuration.incrementFromInstant( Instant.now() );
|
||||
final StoredConfigurationImpl storedConfig = pwmRequest.getConfig().getStoredConfiguration();
|
||||
final String persistentLoginValue = makePersistentLoginPassword( pwmRequest, storedConfig );
|
||||
final PersistentLoginInfo persistentLoginInfo = new PersistentLoginInfo( expirationDate, persistentLoginValue );
|
||||
final String cookieValue = pwmRequest.getPwmApplication().getSecureService().encryptObjectToString( persistentLoginInfo );
|
||||
pwmRequest.getPwmResponse().writeCookie(
|
||||
COOKIE_NAME,
|
||||
cookieValue,
|
||||
persistentSeconds,
|
||||
COOKIE_PATH
|
||||
);
|
||||
LOGGER.debug( pwmRequest, () -> "set persistent config login cookie (expires "
|
||||
+ JavaHelper.toIsoDate( expirationDate )
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkPersistentLoginCookie(
|
||||
final PwmRequest pwmRequest,
|
||||
final StoredConfiguration storedConfig
|
||||
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
final String cookieValue = pwmRequest.readCookie( COOKIE_NAME );
|
||||
if ( !StringUtil.isEmpty( cookieValue ) )
|
||||
{
|
||||
final PersistentLoginInfo persistentLoginInfo = pwmRequest.getPwmApplication().getSecureService().decryptObject( cookieValue, PersistentLoginInfo.class );
|
||||
if ( persistentLoginInfo != null )
|
||||
{
|
||||
if ( persistentLoginInfo.getExpireDate().isAfter( Instant.now() ) )
|
||||
{
|
||||
final String persistentLoginPassword = makePersistentLoginPassword( pwmRequest, storedConfig );
|
||||
if ( StringUtil.nullSafeEquals( persistentLoginPassword, persistentLoginInfo.getPassword() ) )
|
||||
{
|
||||
LOGGER.debug( pwmRequest, () -> "accepting persistent config login from cookie (expires "
|
||||
+ JavaHelper.toIsoDate( persistentLoginInfo.getExpireDate() )
|
||||
+ ")"
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pwmRequest.getPwmResponse().removeCookie( COOKIE_NAME, COOKIE_PATH );
|
||||
LOGGER.debug( pwmRequest, () -> "removing non-working persistent config login cookie" );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
LOGGER.error( pwmRequest, "error examining persistent config login cookie: " + e.getMessage() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static void checkPreconditions(
|
||||
final PwmRequest pwmRequest,
|
||||
final StoredConfigurationImpl storedConfig
|
||||
|
@ -272,164 +144,6 @@ public class ConfigAccessFilter extends AbstractPwmFilter
|
|||
{
|
||||
throw new PwmUnrecoverableException( PwmError.ERROR_UNAUTHORIZED );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean persistentLoginEnabled(
|
||||
final PwmRequest pwmRequest
|
||||
)
|
||||
{
|
||||
if ( pwmRequest.getConfig().isDefaultValue( PwmSetting.PWM_SECURITY_KEY ) )
|
||||
{
|
||||
LOGGER.debug( pwmRequest, () -> "security not available, persistent login not possible." );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String makePersistentLoginPassword(
|
||||
final PwmRequest pwmRequest,
|
||||
final StoredConfiguration storedConfig
|
||||
)
|
||||
throws PwmUnrecoverableException
|
||||
{
|
||||
final int hashChars = 32;
|
||||
String hashValue = storedConfig.readConfigProperty( ConfigurationProperty.PASSWORD_HASH );
|
||||
|
||||
if ( PwmApplicationMode.RUNNING == pwmRequest.getPwmApplication().getApplicationMode() )
|
||||
{
|
||||
final PwmSession pwmSession = pwmRequest.getPwmSession();
|
||||
hashValue += pwmSession.getUserInfo().getUserIdentity().toDelimitedKey();
|
||||
}
|
||||
|
||||
return StringUtil.truncate( SecureEngine.hash( hashValue, PwmHashAlgorithm.SHA512 ), hashChars );
|
||||
}
|
||||
|
||||
private static void forwardToJsp( final PwmRequest pwmRequest )
|
||||
throws ServletException, PwmUnrecoverableException, IOException
|
||||
{
|
||||
final int persistentSeconds = figureMaxLoginSeconds( pwmRequest );
|
||||
final String time = TimeDuration.of( persistentSeconds, TimeDuration.Unit.SECONDS ).asLongString( pwmRequest.getLocale() );
|
||||
|
||||
final ConfigLoginHistory configLoginHistory = readConfigLoginHistory( pwmRequest );
|
||||
|
||||
pwmRequest.setAttribute( PwmRequestAttribute.ConfigLoginHistory, configLoginHistory );
|
||||
pwmRequest.setAttribute( PwmRequestAttribute.ConfigPasswordRememberTime, time );
|
||||
pwmRequest.forwardToJsp( JspUrl.CONFIG_MANAGER_LOGIN );
|
||||
|
||||
}
|
||||
|
||||
private static ConfigLoginHistory readConfigLoginHistory( final PwmRequest pwmRequest )
|
||||
{
|
||||
final ConfigLoginHistory configLoginHistory = pwmRequest.getPwmApplication().readAppAttribute( PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, ConfigLoginHistory.class );
|
||||
return configLoginHistory == null
|
||||
? new ConfigLoginHistory()
|
||||
: configLoginHistory;
|
||||
}
|
||||
|
||||
private static void updateLoginHistory( final PwmRequest pwmRequest, final UserIdentity userIdentity, final boolean successful )
|
||||
{
|
||||
final ConfigLoginHistory configLoginHistory = readConfigLoginHistory( pwmRequest );
|
||||
final ConfigLoginEvent event = new ConfigLoginEvent(
|
||||
userIdentity == null ? "n/a" : userIdentity.toDisplayString(),
|
||||
Instant.now(),
|
||||
pwmRequest.getPwmSession().getSessionStateBean().getSrcAddress()
|
||||
);
|
||||
final int maxEvents = Integer.parseInt( pwmRequest.getPwmApplication().getConfig().readAppProperty( AppProperty.CONFIG_HISTORY_MAX_ITEMS ) );
|
||||
configLoginHistory.addEvent( event, maxEvents, successful );
|
||||
pwmRequest.getPwmApplication().writeAppAttribute( PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, configLoginHistory );
|
||||
}
|
||||
|
||||
@Value
|
||||
private static class PersistentLoginInfo implements Serializable
|
||||
{
|
||||
@SerializedName( "e" )
|
||||
private Instant expireDate;
|
||||
|
||||
@SerializedName( "p" )
|
||||
private String password;
|
||||
}
|
||||
|
||||
@Value
|
||||
public static class ConfigLoginHistory implements Serializable
|
||||
{
|
||||
private List<ConfigLoginEvent> successEvents = new ArrayList<>();
|
||||
private List<ConfigLoginEvent> failedEvents = new ArrayList<>();
|
||||
|
||||
void addEvent( final ConfigLoginEvent event, final int maxEvents, final boolean successful )
|
||||
{
|
||||
final List<ConfigLoginEvent> events = successful ? successEvents : failedEvents;
|
||||
events.add( event );
|
||||
if ( maxEvents > 0 )
|
||||
{
|
||||
while ( events.size() > maxEvents )
|
||||
{
|
||||
events.remove( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConfigLoginEvent> successEvents( )
|
||||
{
|
||||
return Collections.unmodifiableList( successEvents );
|
||||
}
|
||||
|
||||
public List<ConfigLoginEvent> failedEvents( )
|
||||
{
|
||||
return Collections.unmodifiableList( failedEvents );
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
public static class ConfigLoginEvent implements Serializable
|
||||
{
|
||||
private final String userIdentity;
|
||||
private final Instant date;
|
||||
private final String networkAddress;
|
||||
}
|
||||
|
||||
private static int figureMaxLoginSeconds( final PwmRequest pwmRequest )
|
||||
{
|
||||
return JavaHelper.silentParseInt(
|
||||
pwmRequest.getConfig().readAppProperty( AppProperty.CONFIG_MAX_PERSISTENT_LOGIN_SECONDS ),
|
||||
(int) TimeDuration.HOUR.as( TimeDuration.Unit.SECONDS )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static ProcessStatus denyAndError( final PwmRequest pwmRequest, final ErrorInformation errorInformation )
|
||||
throws ServletException, PwmUnrecoverableException, IOException
|
||||
{
|
||||
pwmRequest.respondWithError( errorInformation );
|
||||
return ProcessStatus.Halt;
|
||||
}
|
||||
|
||||
private static ProcessStatus processLoginSuccess( final PwmRequest pwmRequest, final boolean persistentLoginEnabled )
|
||||
throws PwmUnrecoverableException, IOException
|
||||
{
|
||||
final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
|
||||
final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
|
||||
final PwmSession pwmSession = pwmRequest.getPwmSession();
|
||||
|
||||
configManagerBean.setPasswordVerified( true );
|
||||
pwmApplication.getIntruderManager().convenience().clearAddressAndSession( pwmSession );
|
||||
pwmApplication.getIntruderManager().clear( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME );
|
||||
pwmRequest.getPwmSession().getSessionStateBean().setSessionIdRecycleNeeded( true );
|
||||
if ( persistentLoginEnabled && "on".equals( pwmRequest.readParameterAsString( "remember" ) ) )
|
||||
{
|
||||
writePersistentLoginCookie( pwmRequest );
|
||||
}
|
||||
|
||||
if ( configManagerBean.getPrePasswordEntryUrl() != null )
|
||||
{
|
||||
final String originalUrl = configManagerBean.getPrePasswordEntryUrl();
|
||||
configManagerBean.setPrePasswordEntryUrl( null );
|
||||
pwmRequest.getPwmResponse().sendRedirect( originalUrl );
|
||||
return ProcessStatus.Halt;
|
||||
}
|
||||
|
||||
pwmRequest.sendRedirect( pwmRequest.getURLwithQueryString() );
|
||||
return ProcessStatus.Continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import password.pwm.http.servlet.configeditor.ConfigEditorServlet;
|
|||
import password.pwm.http.servlet.configguide.ConfigGuideServlet;
|
||||
import password.pwm.http.servlet.configmanager.ConfigManagerCertificatesServlet;
|
||||
import password.pwm.http.servlet.configmanager.ConfigManagerLocalDBServlet;
|
||||
import password.pwm.http.servlet.configmanager.ConfigManagerLoginServlet;
|
||||
import password.pwm.http.servlet.configmanager.ConfigManagerServlet;
|
||||
import password.pwm.http.servlet.configmanager.ConfigManagerWordlistServlet;
|
||||
import password.pwm.http.servlet.newuser.NewUserServlet;
|
||||
|
@ -90,6 +91,7 @@ public enum PwmServletDefinition
|
|||
ConfigGuide( ConfigGuideServlet.class, ConfigGuideBean.class ),
|
||||
ConfigEditor( ConfigEditorServlet.class, null ),
|
||||
ConfigManager( ConfigManagerServlet.class, ConfigManagerBean.class ),
|
||||
ConfigManager_Login( ConfigManagerLoginServlet.class, ConfigManagerBean.class ),
|
||||
ConfigManager_Wordlists( ConfigManagerWordlistServlet.class, ConfigManagerBean.class ),
|
||||
ConfigManager_LocalDB( ConfigManagerLocalDBServlet.class, ConfigManagerBean.class ),
|
||||
ConfigManager_Certificates( ConfigManagerCertificatesServlet.class, ConfigManagerBean.class ),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
package password.pwm.http.servlet;
|
||||
|
||||
import com.novell.ldapchai.ChaiUser;
|
||||
import com.novell.ldapchai.cr.ChaiChallenge;
|
||||
import com.novell.ldapchai.cr.ChaiCrFactory;
|
||||
import com.novell.ldapchai.cr.ChaiResponseSet;
|
||||
import com.novell.ldapchai.cr.Challenge;
|
||||
|
@ -475,18 +476,30 @@ public class SetupResponsesServlet extends ControlledPwmServlet
|
|||
final Challenge loopChallenge = setupData.getIndexedChallenges().get( indexKey );
|
||||
if ( loopChallenge.isRequired() || !setupData.isSimpleMode() )
|
||||
{
|
||||
|
||||
final Challenge newChallenge;
|
||||
if ( !loopChallenge.isAdminDefined() )
|
||||
{
|
||||
final String questionText = inputMap.get( PwmConstants.PARAM_QUESTION_PREFIX + indexKey );
|
||||
loopChallenge.setChallengeText( questionText );
|
||||
newChallenge = new ChaiChallenge(
|
||||
loopChallenge.isRequired(),
|
||||
questionText,
|
||||
loopChallenge.getMinLength(),
|
||||
loopChallenge.getMaxLength(),
|
||||
loopChallenge.isAdminDefined(),
|
||||
loopChallenge.getMaxQuestionCharsInAnswer(),
|
||||
loopChallenge.isEnforceWordlist()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
newChallenge = loopChallenge;
|
||||
}
|
||||
|
||||
final String answer = inputMap.get( PwmConstants.PARAM_RESPONSE_PREFIX + indexKey );
|
||||
|
||||
if ( answer != null && answer.length() > 0 )
|
||||
{
|
||||
readResponses.put( loopChallenge, answer );
|
||||
readResponses.put( newChallenge, answer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,12 +72,12 @@ import password.pwm.i18n.Message;
|
|||
import password.pwm.i18n.PwmLocaleBundle;
|
||||
import password.pwm.ldap.LdapBrowser;
|
||||
import password.pwm.util.PasswordData;
|
||||
import password.pwm.util.password.RandomPasswordGenerator;
|
||||
import password.pwm.util.java.JsonUtil;
|
||||
import password.pwm.util.java.StringUtil;
|
||||
import password.pwm.util.java.TimeDuration;
|
||||
import password.pwm.util.logging.PwmLogger;
|
||||
import password.pwm.util.macro.MacroMachine;
|
||||
import password.pwm.util.password.RandomPasswordGenerator;
|
||||
import password.pwm.util.queue.SmsQueueManager;
|
||||
import password.pwm.util.secure.HttpsServerCertificateManager;
|
||||
import password.pwm.ws.server.RestResultBean;
|
||||
|
@ -164,8 +164,11 @@ public class ConfigEditorServlet extends ControlledPwmServlet
|
|||
}
|
||||
|
||||
@Override
|
||||
public ProcessStatus preProcessCheck( final PwmRequest pwmRequest ) throws PwmUnrecoverableException, IOException, ServletException
|
||||
public ProcessStatus preProcessCheck( final PwmRequest pwmRequest )
|
||||
throws PwmUnrecoverableException, IOException, ServletException
|
||||
{
|
||||
ConfigManagerServlet.verifyConfigAccess( pwmRequest );
|
||||
|
||||
final ConfigManagerBean configManagerBean = getBean( pwmRequest );
|
||||
|
||||
if ( configManagerBean.getStoredConfiguration() == null )
|
||||
|
|
|
@ -98,6 +98,8 @@ public class ConfigManagerCertificatesServlet extends AbstractPwmServlet
|
|||
protected void processAction( final PwmRequest pwmRequest )
|
||||
throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
|
||||
{
|
||||
ConfigManagerServlet.verifyConfigAccess( pwmRequest );
|
||||
|
||||
final ConfigManagerCertificateAction action = readProcessAction( pwmRequest );
|
||||
final ArrayList<CertificateDebugDataItem> certificateDebugDataItems = new ArrayList<>( makeCertificateDebugData( pwmRequest.getConfig() ) );
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
package password.pwm.http.servlet.configmanager;
|
||||
|
||||
import com.novell.ldapchai.exception.ChaiUnavailableException;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import password.pwm.AppProperty;
|
||||
import password.pwm.PwmApplication;
|
||||
|
@ -103,8 +102,9 @@ public class ConfigManagerLocalDBServlet extends AbstractPwmServlet
|
|||
}
|
||||
|
||||
protected void processAction( final PwmRequest pwmRequest )
|
||||
throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
|
||||
throws ServletException, IOException, PwmUnrecoverableException
|
||||
{
|
||||
ConfigManagerServlet.verifyConfigAccess( pwmRequest );
|
||||
|
||||
final ConfigManagerAction processAction = readProcessAction( pwmRequest );
|
||||
if ( processAction != null )
|
||||
|
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Password Management Servlets (PWM)
|
||||
* http://www.pwm-project.org
|
||||
*
|
||||
* Copyright (c) 2006-2009 Novell, Inc.
|
||||
* Copyright (c) 2009-2019 The PWM Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package password.pwm.http.servlet.configmanager;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.novell.ldapchai.exception.ChaiUnavailableException;
|
||||
import lombok.Value;
|
||||
import password.pwm.AppProperty;
|
||||
import password.pwm.PwmApplication;
|
||||
import password.pwm.PwmApplicationMode;
|
||||
import password.pwm.PwmConstants;
|
||||
import password.pwm.bean.UserIdentity;
|
||||
import password.pwm.config.PwmSetting;
|
||||
import password.pwm.config.stored.ConfigurationProperty;
|
||||
import password.pwm.config.stored.ConfigurationReader;
|
||||
import password.pwm.config.stored.StoredConfiguration;
|
||||
import password.pwm.config.stored.StoredConfigurationImpl;
|
||||
import password.pwm.error.ErrorInformation;
|
||||
import password.pwm.error.PwmError;
|
||||
import password.pwm.error.PwmUnrecoverableException;
|
||||
import password.pwm.http.ContextManager;
|
||||
import password.pwm.http.HttpMethod;
|
||||
import password.pwm.http.JspUrl;
|
||||
import password.pwm.http.ProcessStatus;
|
||||
import password.pwm.http.PwmHttpResponseWrapper;
|
||||
import password.pwm.http.PwmRequest;
|
||||
import password.pwm.http.PwmRequestAttribute;
|
||||
import password.pwm.http.PwmSession;
|
||||
import password.pwm.http.bean.ConfigManagerBean;
|
||||
import password.pwm.http.servlet.AbstractPwmServlet;
|
||||
import password.pwm.http.servlet.PwmServletDefinition;
|
||||
import password.pwm.svc.intruder.RecordType;
|
||||
import password.pwm.util.java.JavaHelper;
|
||||
import password.pwm.util.java.StringUtil;
|
||||
import password.pwm.util.java.TimeDuration;
|
||||
import password.pwm.util.logging.PwmLogger;
|
||||
import password.pwm.util.secure.PwmHashAlgorithm;
|
||||
import password.pwm.util.secure.SecureEngine;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@WebServlet(
|
||||
name = "ConfigManagerLogin",
|
||||
urlPatterns = {
|
||||
PwmConstants.URL_PREFIX_PRIVATE + "/config/login",
|
||||
}
|
||||
)
|
||||
public class ConfigManagerLoginServlet extends AbstractPwmServlet
|
||||
{
|
||||
private static final PwmLogger LOGGER = PwmLogger.forClass( ConfigManagerLoginServlet.class );
|
||||
|
||||
private static final String COOKIE_NAME = PwmConstants.COOKIE_PERSISTENT_CONFIG_LOGIN;
|
||||
private static final PwmHttpResponseWrapper.CookiePath COOKIE_PATH = PwmHttpResponseWrapper.CookiePath.CurrentURL;
|
||||
|
||||
public enum ConfigManagerLoginAction implements ProcessAction
|
||||
{
|
||||
login( HttpMethod.POST ),;
|
||||
|
||||
private final HttpMethod method;
|
||||
|
||||
ConfigManagerLoginAction( final HttpMethod method )
|
||||
{
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public Collection<HttpMethod> permittedMethods( )
|
||||
{
|
||||
return Collections.singletonList( method );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processAction( final PwmRequest pwmRequest )
|
||||
throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
|
||||
{
|
||||
checkPersistentLoginCookie( pwmRequest );
|
||||
|
||||
final ConfigManagerLoginAction processAction = readProcessAction( pwmRequest );
|
||||
if ( processAction != null )
|
||||
{
|
||||
switch ( processAction )
|
||||
{
|
||||
case login:
|
||||
processLoginRequest( pwmRequest );
|
||||
break;
|
||||
|
||||
default:
|
||||
JavaHelper.unhandledSwitchStatement( processAction );
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
|
||||
if ( configManagerBean.isPasswordVerified() )
|
||||
{
|
||||
forwardToNextUrl( pwmRequest );
|
||||
return;
|
||||
|
||||
}
|
||||
forwardToJsp( pwmRequest );
|
||||
}
|
||||
|
||||
protected void processLoginRequest( final PwmRequest pwmRequest )
|
||||
throws PwmUnrecoverableException, IOException, ServletException
|
||||
{
|
||||
final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
|
||||
final ConfigurationReader runningConfigReader = ContextManager.getContextManager( pwmRequest.getHttpServletRequest().getSession() ).getConfigReader();
|
||||
final StoredConfigurationImpl storedConfig = runningConfigReader.getStoredConfiguration();
|
||||
|
||||
final String password = pwmRequest.readParameterAsString( "password" );
|
||||
if ( !StringUtil.isEmpty( password ) )
|
||||
{
|
||||
if ( storedConfig.verifyPassword( password, pwmRequest.getConfig() ) )
|
||||
{
|
||||
LOGGER.trace( pwmRequest, () -> "valid configuration password accepted" );
|
||||
updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), true );
|
||||
processLoginSuccess( pwmRequest, true );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.trace( pwmRequest, () -> "configuration password is not correct" );
|
||||
pwmApplication.getIntruderManager().convenience().markAddressAndSession( pwmRequest.getPwmSession() );
|
||||
pwmApplication.getIntruderManager().mark( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME, pwmRequest.getSessionLabel() );
|
||||
final ErrorInformation errorInformation = new ErrorInformation( PwmError.ERROR_PASSWORD_ONLY_BAD );
|
||||
updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), false );
|
||||
setLastError( pwmRequest, errorInformation );
|
||||
forwardToJsp( pwmRequest );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ConfigManagerLoginAction readProcessAction( final PwmRequest request )
|
||||
throws PwmUnrecoverableException
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigManagerLoginAction.valueOf( request.readParameterAsString( PwmConstants.PARAM_ACTION_REQUEST ) );
|
||||
}
|
||||
catch ( IllegalArgumentException e )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void forwardToJsp( final PwmRequest pwmRequest )
|
||||
throws ServletException, PwmUnrecoverableException, IOException
|
||||
{
|
||||
final int persistentSeconds = figureMaxLoginSeconds( pwmRequest );
|
||||
final String time = TimeDuration.of( persistentSeconds, TimeDuration.Unit.SECONDS ).asLongString( pwmRequest.getLocale() );
|
||||
|
||||
final ConfigLoginHistory configLoginHistory = readConfigLoginHistory( pwmRequest );
|
||||
|
||||
pwmRequest.setAttribute( PwmRequestAttribute.ConfigLoginHistory, configLoginHistory );
|
||||
pwmRequest.setAttribute( PwmRequestAttribute.ConfigPasswordRememberTime, time );
|
||||
pwmRequest.forwardToJsp( JspUrl.CONFIG_MANAGER_LOGIN );
|
||||
}
|
||||
|
||||
|
||||
private static ConfigLoginHistory readConfigLoginHistory( final PwmRequest pwmRequest )
|
||||
{
|
||||
final ConfigLoginHistory configLoginHistory = pwmRequest.getPwmApplication().readAppAttribute( PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, ConfigLoginHistory.class );
|
||||
return configLoginHistory == null
|
||||
? new ConfigLoginHistory()
|
||||
: configLoginHistory;
|
||||
}
|
||||
|
||||
private static void updateLoginHistory( final PwmRequest pwmRequest, final UserIdentity userIdentity, final boolean successful )
|
||||
{
|
||||
final ConfigLoginHistory configLoginHistory = readConfigLoginHistory( pwmRequest );
|
||||
final ConfigLoginEvent event = new ConfigLoginEvent(
|
||||
userIdentity == null ? "n/a" : userIdentity.toDisplayString(),
|
||||
Instant.now(),
|
||||
pwmRequest.getPwmSession().getSessionStateBean().getSrcAddress()
|
||||
);
|
||||
final int maxEvents = Integer.parseInt( pwmRequest.getPwmApplication().getConfig().readAppProperty( AppProperty.CONFIG_HISTORY_MAX_ITEMS ) );
|
||||
configLoginHistory.addEvent( event, maxEvents, successful );
|
||||
pwmRequest.getPwmApplication().writeAppAttribute( PwmApplication.AppAttribute.CONFIG_LOGIN_HISTORY, configLoginHistory );
|
||||
}
|
||||
|
||||
@Value
|
||||
public static class ConfigLoginHistory implements Serializable
|
||||
{
|
||||
private List<ConfigLoginEvent> successEvents = new ArrayList<>();
|
||||
private List<ConfigLoginEvent> failedEvents = new ArrayList<>();
|
||||
|
||||
void addEvent( final ConfigLoginEvent event, final int maxEvents, final boolean successful )
|
||||
{
|
||||
final List<ConfigLoginEvent> events = successful ? successEvents : failedEvents;
|
||||
events.add( event );
|
||||
if ( maxEvents > 0 )
|
||||
{
|
||||
while ( events.size() > maxEvents )
|
||||
{
|
||||
events.remove( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConfigLoginEvent> successEvents( )
|
||||
{
|
||||
return Collections.unmodifiableList( successEvents );
|
||||
}
|
||||
|
||||
public List<ConfigLoginEvent> failedEvents( )
|
||||
{
|
||||
return Collections.unmodifiableList( failedEvents );
|
||||
}
|
||||
}
|
||||
|
||||
@Value
|
||||
public static class ConfigLoginEvent implements Serializable
|
||||
{
|
||||
private final String userIdentity;
|
||||
private final Instant date;
|
||||
private final String networkAddress;
|
||||
}
|
||||
|
||||
private static ProcessStatus processLoginSuccess( final PwmRequest pwmRequest, final boolean persistentLoginEnabled )
|
||||
throws PwmUnrecoverableException, IOException
|
||||
{
|
||||
final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
|
||||
final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
|
||||
final PwmSession pwmSession = pwmRequest.getPwmSession();
|
||||
|
||||
configManagerBean.setPasswordVerified( true );
|
||||
pwmApplication.getIntruderManager().convenience().clearAddressAndSession( pwmSession );
|
||||
pwmApplication.getIntruderManager().clear( RecordType.USERNAME, PwmConstants.CONFIGMANAGER_INTRUDER_USERNAME );
|
||||
pwmRequest.getPwmSession().getSessionStateBean().setSessionIdRecycleNeeded( true );
|
||||
if ( persistentLoginEnabled && "on".equals( pwmRequest.readParameterAsString( "remember" ) ) )
|
||||
{
|
||||
writePersistentLoginCookie( pwmRequest );
|
||||
}
|
||||
|
||||
if ( configManagerBean.getPrePasswordEntryUrl() != null )
|
||||
{
|
||||
final String originalUrl = configManagerBean.getPrePasswordEntryUrl();
|
||||
configManagerBean.setPrePasswordEntryUrl( null );
|
||||
pwmRequest.getPwmResponse().sendRedirect( originalUrl );
|
||||
return ProcessStatus.Halt;
|
||||
}
|
||||
|
||||
pwmRequest.sendRedirect( pwmRequest.getURLwithQueryString() );
|
||||
return ProcessStatus.Continue;
|
||||
}
|
||||
|
||||
private static void forwardToNextUrl( final PwmRequest pwmRequest )
|
||||
throws IOException, PwmUnrecoverableException
|
||||
{
|
||||
final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
|
||||
|
||||
if ( configManagerBean.getPrePasswordEntryUrl() != null )
|
||||
{
|
||||
final String originalUrl = configManagerBean.getPrePasswordEntryUrl();
|
||||
configManagerBean.setPrePasswordEntryUrl( null );
|
||||
pwmRequest.getPwmResponse().sendRedirect( originalUrl );
|
||||
return;
|
||||
}
|
||||
|
||||
pwmRequest.sendRedirect( PwmServletDefinition.ConfigManager );
|
||||
}
|
||||
|
||||
|
||||
public static void writePersistentLoginCookie( final PwmRequest pwmRequest )
|
||||
throws PwmUnrecoverableException
|
||||
{
|
||||
final int persistentSeconds = figureMaxLoginSeconds( pwmRequest );
|
||||
|
||||
if ( persistentSeconds > 0 )
|
||||
{
|
||||
final TimeDuration persistenceDuration = TimeDuration.of( persistentSeconds, TimeDuration.Unit.SECONDS );
|
||||
final Instant expirationDate = persistenceDuration.incrementFromInstant( Instant.now() );
|
||||
final StoredConfigurationImpl storedConfig = pwmRequest.getConfig().getStoredConfiguration();
|
||||
final String persistentLoginValue = makePersistentLoginPassword( pwmRequest, storedConfig );
|
||||
final PersistentLoginInfo persistentLoginInfo = new PersistentLoginInfo( expirationDate, persistentLoginValue );
|
||||
final String cookieValue = pwmRequest.getPwmApplication().getSecureService().encryptObjectToString( persistentLoginInfo );
|
||||
pwmRequest.getPwmResponse().writeCookie(
|
||||
COOKIE_NAME,
|
||||
cookieValue,
|
||||
persistentSeconds,
|
||||
COOKIE_PATH
|
||||
);
|
||||
LOGGER.debug( pwmRequest, () -> "set persistent config login cookie (expires "
|
||||
+ JavaHelper.toIsoDate( expirationDate )
|
||||
+ ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPersistentLoginCookie(
|
||||
final PwmRequest pwmRequest
|
||||
)
|
||||
throws PwmUnrecoverableException
|
||||
{
|
||||
if ( !persistentLoginEnabled( pwmRequest ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final ConfigurationReader runningConfigReader = ContextManager.getContextManager( pwmRequest.getHttpServletRequest().getSession() ).getConfigReader();
|
||||
final StoredConfigurationImpl storedConfig = runningConfigReader.getStoredConfiguration();
|
||||
|
||||
try
|
||||
{
|
||||
final String cookieValue = pwmRequest.readCookie( COOKIE_NAME );
|
||||
if ( !StringUtil.isEmpty( cookieValue ) )
|
||||
{
|
||||
final PersistentLoginInfo persistentLoginInfo = pwmRequest.getPwmApplication().getSecureService().decryptObject( cookieValue, PersistentLoginInfo.class );
|
||||
if ( persistentLoginInfo != null )
|
||||
{
|
||||
if ( persistentLoginInfo.getExpireDate().isAfter( Instant.now() ) )
|
||||
{
|
||||
final String persistentLoginPassword = makePersistentLoginPassword( pwmRequest, storedConfig );
|
||||
if ( StringUtil.nullSafeEquals( persistentLoginPassword, persistentLoginInfo.getPassword() ) )
|
||||
{
|
||||
LOGGER.debug( pwmRequest, () -> "accepting persistent config login from cookie (expires "
|
||||
+ JavaHelper.toIsoDate( persistentLoginInfo.getExpireDate() )
|
||||
+ ")"
|
||||
);
|
||||
|
||||
final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
|
||||
configManagerBean.setPasswordVerified( true );
|
||||
}
|
||||
}
|
||||
|
||||
pwmRequest.getPwmResponse().removeCookie( COOKIE_NAME, COOKIE_PATH );
|
||||
LOGGER.debug( pwmRequest, () -> "removing non-working persistent config login cookie" );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
LOGGER.error( pwmRequest, "error examining persistent config login cookie: " + e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Value
|
||||
private static class PersistentLoginInfo implements Serializable
|
||||
{
|
||||
@SerializedName( "e" )
|
||||
private Instant expireDate;
|
||||
|
||||
@SerializedName( "p" )
|
||||
private String password;
|
||||
}
|
||||
|
||||
public static int figureMaxLoginSeconds( final PwmRequest pwmRequest )
|
||||
{
|
||||
return JavaHelper.silentParseInt(
|
||||
pwmRequest.getConfig().readAppProperty( AppProperty.CONFIG_MAX_PERSISTENT_LOGIN_SECONDS ),
|
||||
(int) TimeDuration.HOUR.as( TimeDuration.Unit.SECONDS )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static String makePersistentLoginPassword(
|
||||
final PwmRequest pwmRequest,
|
||||
final StoredConfiguration storedConfig
|
||||
)
|
||||
throws PwmUnrecoverableException
|
||||
{
|
||||
final int hashChars = 32;
|
||||
String hashValue = storedConfig.readConfigProperty( ConfigurationProperty.PASSWORD_HASH );
|
||||
|
||||
if ( PwmApplicationMode.RUNNING == pwmRequest.getPwmApplication().getApplicationMode() )
|
||||
{
|
||||
final PwmSession pwmSession = pwmRequest.getPwmSession();
|
||||
hashValue += pwmSession.getUserInfo().getUserIdentity().toDelimitedKey();
|
||||
}
|
||||
|
||||
return StringUtil.truncate( SecureEngine.hash( hashValue, PwmHashAlgorithm.SHA512 ), hashChars );
|
||||
}
|
||||
|
||||
|
||||
private static boolean persistentLoginEnabled(
|
||||
final PwmRequest pwmRequest
|
||||
)
|
||||
{
|
||||
if ( pwmRequest.getConfig().isDefaultValue( PwmSetting.PWM_SECURITY_KEY ) )
|
||||
{
|
||||
LOGGER.debug( pwmRequest, () -> "security not available, persistent login not possible." );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -39,11 +39,13 @@ import password.pwm.http.HttpContentType;
|
|||
import password.pwm.http.HttpHeader;
|
||||
import password.pwm.http.HttpMethod;
|
||||
import password.pwm.http.JspUrl;
|
||||
import password.pwm.http.ProcessStatus;
|
||||
import password.pwm.http.PwmRequest;
|
||||
import password.pwm.http.PwmRequestAttribute;
|
||||
import password.pwm.http.PwmResponse;
|
||||
import password.pwm.http.PwmSession;
|
||||
import password.pwm.http.bean.ConfigManagerBean;
|
||||
import password.pwm.http.filter.ConfigAccessFilter;
|
||||
import password.pwm.http.servlet.AbstractPwmServlet;
|
||||
import password.pwm.http.servlet.PwmServletDefinition;
|
||||
import password.pwm.http.servlet.configguide.ConfigGuideUtils;
|
||||
|
@ -121,9 +123,23 @@ public class ConfigManagerServlet extends AbstractPwmServlet
|
|||
}
|
||||
}
|
||||
|
||||
public static void verifyConfigAccess( final PwmRequest pwmRequest )
|
||||
throws ServletException, PwmUnrecoverableException, IOException
|
||||
{
|
||||
final ConfigManagerBean configManagerBean = pwmRequest.getPwmApplication().getSessionStateService().getBean( pwmRequest, ConfigManagerBean.class );
|
||||
final ProcessStatus processStatus = ConfigAccessFilter.checkAuthentication( pwmRequest, configManagerBean );
|
||||
if ( processStatus != ProcessStatus.Continue )
|
||||
{
|
||||
final String msg = "config access authentication not yet completed";
|
||||
throw PwmUnrecoverableException.newException( PwmError.ERROR_SERVICE_NOT_AVAILABLE, msg );
|
||||
}
|
||||
}
|
||||
|
||||
protected void processAction( final PwmRequest pwmRequest )
|
||||
throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
|
||||
{
|
||||
verifyConfigAccess( pwmRequest );
|
||||
|
||||
final ConfigManagerAction processAction = readProcessAction( pwmRequest );
|
||||
if ( processAction != null )
|
||||
{
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
package password.pwm.http.servlet.configmanager;
|
||||
|
||||
import com.novell.ldapchai.exception.ChaiUnavailableException;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
|
@ -102,8 +101,9 @@ public class ConfigManagerWordlistServlet extends AbstractPwmServlet
|
|||
}
|
||||
|
||||
protected void processAction( final PwmRequest pwmRequest )
|
||||
throws ServletException, IOException, ChaiUnavailableException, PwmUnrecoverableException
|
||||
throws ServletException, IOException, PwmUnrecoverableException
|
||||
{
|
||||
ConfigManagerServlet.verifyConfigAccess( pwmRequest );
|
||||
|
||||
final ConfigManagerAction processAction = readProcessAction( pwmRequest );
|
||||
if ( processAction != null )
|
||||
|
|
|
@ -51,8 +51,7 @@ class ResourceFileRequest
|
|||
private static final PwmLogger LOGGER = PwmLogger.forClass( ResourceFileRequest.class );
|
||||
|
||||
private static final Map<String, String> WEB_JAR_VERSION_MAP = Collections.unmodifiableMap( new HashMap<>( new WebJarAssetLocator().getWebJars() ) );
|
||||
private static final Collection<String> WEB_JAR_ASSET_LIST = Collections.unmodifiableCollection( new ArrayList<>( new WebJarAssetLocator().getFullPathIndex().values() ) );
|
||||
|
||||
private static final Collection<String> WEB_JAR_ASSET_LIST = Collections.unmodifiableCollection( new ArrayList<>( new WebJarAssetLocator().listAssets() ) );
|
||||
private final HttpServletRequest httpServletRequest;
|
||||
private final Configuration configuration;
|
||||
private final ResourceServletConfiguration resourceServletConfiguration;
|
||||
|
|
|
@ -78,19 +78,23 @@ class ReportSettings implements Serializable
|
|||
{
|
||||
final ReportSettings.ReportSettingsBuilder builder = ReportSettings.builder();
|
||||
builder.maxCacheAge( TimeDuration.of( Long.parseLong( config.readAppProperty( AppProperty.REPORTING_MAX_REPORT_AGE_SECONDS ) ), TimeDuration.Unit.SECONDS ) );
|
||||
builder.searchFilter( config.readSettingAsUserPermission( PwmSetting.REPORTING_USER_MATCH ) );
|
||||
builder.maxSearchSize ( ( int ) config.readSettingAsLong( PwmSetting.REPORTING_MAX_QUERY_SIZE ) );
|
||||
builder.dailyJobEnabled( config.readSettingAsBoolean( PwmSetting.REPORTING_ENABLE_DAILY_JOB ) );
|
||||
|
||||
if ( builder.searchFilter == null || builder.searchFilter.isEmpty() )
|
||||
{
|
||||
builder.searchFilter = null;
|
||||
final List<UserPermission> searchFilter = config.readSettingAsUserPermission( PwmSetting.REPORTING_USER_MATCH );
|
||||
if ( searchFilter != null && !searchFilter.isEmpty() )
|
||||
{
|
||||
builder.searchFilter( searchFilter );
|
||||
}
|
||||
}
|
||||
|
||||
builder.jobOffsetSeconds = ( int ) config.readSettingAsLong( PwmSetting.REPORTING_JOB_TIME_OFFSET );
|
||||
if ( builder.jobOffsetSeconds > 60 * 60 * 24 )
|
||||
{
|
||||
builder.jobOffsetSeconds = 0;
|
||||
final int jobOffsetSeconds = ( int ) config.readSettingAsLong( PwmSetting.REPORTING_JOB_TIME_OFFSET );
|
||||
if ( jobOffsetSeconds <= 60 * 60 * 24 )
|
||||
{
|
||||
builder.jobOffsetSeconds( jobOffsetSeconds );
|
||||
}
|
||||
}
|
||||
|
||||
builder.trackDays( parseDayIntervalStr( config ) );
|
||||
|
|
|
@ -338,16 +338,19 @@ public class CaptchaUtility
|
|||
final String configValue = pwmRequest.getConfig().readSettingAsString( PwmSetting.CAPTCHA_SKIP_PARAM );
|
||||
if ( !StringUtil.isEmpty( configValue ) )
|
||||
{
|
||||
final String skipCaptcha = pwmRequest.readParameterAsString( PwmConstants.PARAM_SKIP_CAPTCHA );
|
||||
if ( StringUtil.nullSafeEquals( configValue, skipCaptcha ) )
|
||||
final String requestValue = pwmRequest.readParameterAsString( PwmConstants.PARAM_SKIP_CAPTCHA );
|
||||
if ( !StringUtil.isEmpty( requestValue ) )
|
||||
{
|
||||
LOGGER.trace( pwmRequest, () -> "valid skipCaptcha value in request, skipping captcha check for this session" );
|
||||
pwmRequest.getPwmSession().getSessionStateBean().setCaptchaBypassedViaParameter( true );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.error( pwmRequest, "skipCaptcha value is in request, however value '" + skipCaptcha + "' does not match configured value" );
|
||||
if ( StringUtil.nullSafeEquals( configValue, requestValue ) )
|
||||
{
|
||||
LOGGER.trace( pwmRequest, () -> "valid skipCaptcha value in request, skipping captcha check for this session" );
|
||||
pwmRequest.getPwmSession().getSessionStateBean().setCaptchaBypassedViaParameter( true );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.error( pwmRequest, "skipCaptcha value is in request, however value '" + requestValue + "' does not match configured value" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ public class MBeanUtility
|
|||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
LOGGER.error( "error registering mbean: " + e.getMessage() );
|
||||
LOGGER.debug( () -> "error registering mbean: " + e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class MBeanUtility
|
|||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
LOGGER.error( "error unregistering mbean: " + e.getMessage() );
|
||||
LOGGER.debug( () -> "error unregistering mbean: " + e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ import password.pwm.config.option.DataStorageMethod;
|
|||
import password.pwm.error.PwmUnrecoverableException;
|
||||
import password.pwm.util.logging.PwmLogger;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -119,7 +118,7 @@ public interface CrOperator
|
|||
);
|
||||
responseInfoBean.setTimestamp( responseSet.getTimestamp() == null
|
||||
? null
|
||||
: Instant.ofEpochMilli( responseSet.getTimestamp().getTime() )
|
||||
: responseSet.getTimestamp()
|
||||
);
|
||||
return responseInfoBean;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,6 @@ import java.security.Security;
|
|||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -620,7 +619,7 @@ public class NMASCrOperator implements CrOperator
|
|||
}
|
||||
|
||||
@Override
|
||||
public Date getTimestamp( ) throws ChaiUnavailableException, IllegalStateException, ChaiOperationException
|
||||
public Instant getTimestamp( ) throws ChaiUnavailableException, IllegalStateException, ChaiOperationException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>org.pwm-project</groupId>
|
||||
<artifactId>pwm-parent</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.9.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -181,7 +181,7 @@
|
|||
<!-- builds xml file of dependencies and licenses for use in about page -->
|
||||
<groupId>com.github.jinnovations</groupId>
|
||||
<artifactId>attribution-maven-plugin</artifactId>
|
||||
<version>0.9.5</version>
|
||||
<version>0.9.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
@ -285,22 +285,22 @@
|
|||
<dependency>
|
||||
<groupId>org.webjars.npm</groupId>
|
||||
<artifactId>dojo</artifactId>
|
||||
<version>1.15.0</version>
|
||||
<version>1.16.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars.npm</groupId>
|
||||
<artifactId>dijit</artifactId>
|
||||
<version>1.15.0</version>
|
||||
<version>1.16.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars.npm</groupId>
|
||||
<artifactId>dojox</artifactId>
|
||||
<version>1.15.0</version>
|
||||
<version>1.16.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars.npm</groupId>
|
||||
<artifactId>dgrid</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<version>1.3.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars.bower</groupId>
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
<exclude>.node/**</exclude>
|
||||
<exclude>dist/**</exclude>
|
||||
<exclude>node_modules/**</exclude>
|
||||
<exclude>angular/dist/**</exclude>
|
||||
<exclude>angular/node_modules/**</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
<%@ page import="password.pwm.util.i18n.LocaleHelper" %>
|
||||
<%@ page import="password.pwm.util.java.JavaHelper" %>
|
||||
<%@ page import="password.pwm.http.PwmRequestAttribute" %>
|
||||
<%@ page import="password.pwm.http.servlet.configmanager.ConfigManagerServlet" %>
|
||||
<%@ page import="password.pwm.http.servlet.configmanager.ConfigManagerLoginServlet" %>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
|
@ -66,11 +68,12 @@
|
|||
<pwm:if test="<%=PwmIfTest.showIcons%>"><span class="btn-icon pwm-icon pwm-icon-sign-in"></span></pwm:if>
|
||||
<pwm:display key="Button_Login"/>
|
||||
</button>
|
||||
<input type="hidden" name="processAction" value="<%=ConfigManagerLoginServlet.ConfigManagerLoginAction.login%>"/>
|
||||
<%@ include file="/WEB-INF/jsp/fragment/cancel-button.jsp" %>
|
||||
<input type="hidden" id="pwmFormID" name="pwmFormID" value="<pwm:FormID/>" autofocus/>
|
||||
</div>
|
||||
</form>
|
||||
<% final ConfigAccessFilter.ConfigLoginHistory configLoginHistory = (ConfigAccessFilter.ConfigLoginHistory)JspUtility.getAttribute(pageContext, PwmRequestAttribute.ConfigLoginHistory); %>
|
||||
<% final ConfigManagerLoginServlet.ConfigLoginHistory configLoginHistory = (ConfigManagerLoginServlet.ConfigLoginHistory)JspUtility.getAttribute(pageContext, PwmRequestAttribute.ConfigLoginHistory); %>
|
||||
<% if (configLoginHistory != null && !configLoginHistory.successEvents().isEmpty()) { %>
|
||||
<h2 style="margin-top: 15px;">Previous Authentications</h2>
|
||||
<table>
|
||||
|
@ -79,7 +82,7 @@
|
|||
<td class="title">Timestamp</td>
|
||||
<td class="title">Network Address</td>
|
||||
</tr>
|
||||
<% for (final ConfigAccessFilter.ConfigLoginEvent event : configLoginHistory.successEvents()) { %>
|
||||
<% for (final ConfigManagerLoginServlet.ConfigLoginEvent event : configLoginHistory.successEvents()) { %>
|
||||
<tr>
|
||||
<td><%=event.getUserIdentity()%></td>
|
||||
<td><span class="timestamp"><%=JavaHelper.toIsoDate(event.getDate())%></span></td>
|
||||
|
@ -97,7 +100,7 @@
|
|||
<td class="title">Timestamp</td>
|
||||
<td class="title">Network Address</td>
|
||||
</tr>
|
||||
<% for (final ConfigAccessFilter.ConfigLoginEvent event : configLoginHistory.failedEvents()) { %>
|
||||
<% for (final ConfigManagerLoginServlet.ConfigLoginEvent event : configLoginHistory.failedEvents()) { %>
|
||||
<tr>
|
||||
<td><%=event.getUserIdentity()%></td>
|
||||
<td><span class="timestamp"><%=JavaHelper.toIsoDate(event.getDate())%></span></td>
|
||||
|
|
Loading…
Reference in a new issue