You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2017/01/05 18:27:15 UTC

[1/5] incubator-guacamole-client git commit: GUACAMOLE-36: Add password reset date to schema.

Repository: incubator-guacamole-client
Updated Branches:
  refs/heads/master 565028565 -> 102d52f0f


GUACAMOLE-36: Add password reset date to schema.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/a2074112
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/a2074112
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/a2074112

Branch: refs/heads/master
Commit: a207411241a6a4bbdab80f4f8aba4da6b89be845
Parents: 66f00ad
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Aug 22 12:01:58 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jan 3 20:55:42 2017 -0800

----------------------------------------------------------------------
 .../guacamole/auth/jdbc/user/UserModel.java     | 30 ++++++++++++++++++++
 .../schema/001-create-schema.sql                |  1 +
 .../schema/upgrade/upgrade-pre-0.9.11.sql       | 25 ++++++++++++++++
 .../guacamole/auth/jdbc/user/UserMapper.xml     |  7 +++++
 .../schema/001-create-schema.sql                |  1 +
 .../schema/upgrade/upgrade-pre-0.9.11.sql       | 25 ++++++++++++++++
 .../guacamole/auth/jdbc/user/UserMapper.xml     |  7 +++++
 7 files changed, 96 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java
index 09de5e8..5e81b3d 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserModel.java
@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.user;
 
 import java.sql.Date;
 import java.sql.Time;
+import java.sql.Timestamp;
 import org.apache.guacamole.auth.jdbc.base.ObjectModel;
 
 /**
@@ -42,6 +43,11 @@ public class UserModel extends ObjectModel {
     private byte[] passwordSalt;
 
     /**
+     * The time this user's password was last reset.
+     */
+    private Timestamp passwordDate;
+
+    /**
      * Whether the user account is disabled. Disabled accounts exist and can
      * be modified, but cannot be used.
      */
@@ -144,6 +150,30 @@ public class UserModel extends ObjectModel {
     }
 
     /**
+     * Returns the date that this user's password was last set/reset. This
+     * value is required to be manually updated whenever the user's password is
+     * changed; it will not be automatically updated by the database.
+     *
+     * @return
+     *     The date that this user's password was last set/reset.
+     */
+    public Timestamp getPasswordDate() {
+        return passwordDate;
+    }
+
+    /**
+     * Sets the date that this user's password was last set/reset. This
+     * value is required to be manually updated whenever the user's password is
+     * changed; it will not be automatically updated by the database.
+     *
+     * @param passwordDate
+     *     The date that this user's password was last set/reset.
+     */
+    public void setPasswordDate(Timestamp passwordDate) {
+        this.passwordDate = passwordDate;
+    }
+
+    /**
      * Returns whether the user has been disabled. Disabled users are not
      * allowed to login. Although their account data exists, all login attempts
      * will fail as if the account does not exist.

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql
index e1b19b0..cb56047 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/001-create-schema.sql
@@ -85,6 +85,7 @@ CREATE TABLE `guacamole_user` (
   `username`      varchar(128) NOT NULL,
   `password_hash` binary(32)   NOT NULL,
   `password_salt` binary(32),
+  `password_date` datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP,
 
   -- Account disabled/expired status
   `disabled`      boolean      NOT NULL DEFAULT 0,

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.11.sql
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.11.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.11.sql
new file mode 100644
index 0000000..3acc2a4
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.11.sql
@@ -0,0 +1,25 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+--
+
+--
+-- Add per-user password set date
+--
+
+ALTER TABLE guacamole_user
+    ADD COLUMN password_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
index 65dc97c..3530b0b 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
@@ -29,6 +29,7 @@
         <result column="username"            property="identifier"        jdbcType="VARCHAR"/>
         <result column="password_hash"       property="passwordHash"      jdbcType="BINARY"/>
         <result column="password_salt"       property="passwordSalt"      jdbcType="BINARY"/>
+        <result column="password_date"       property="passwordDate"      jdbcType="TIMESTAMP"/>
         <result column="disabled"            property="disabled"          jdbcType="BOOLEAN"/>
         <result column="access_window_start" property="accessWindowStart" jdbcType="TIME"/>
         <result column="access_window_end"   property="accessWindowEnd"   jdbcType="TIME"/>
@@ -61,6 +62,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -85,6 +87,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -112,6 +115,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -139,6 +143,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -151,6 +156,7 @@
             #{object.identifier,jdbcType=VARCHAR},
             #{object.passwordHash,jdbcType=BINARY},
             #{object.passwordSalt,jdbcType=BINARY},
+            #{object.passwordDate,jdbcType=TIMESTAMP},
             #{object.disabled,jdbcType=BOOLEAN},
             #{object.expired,jdbcType=BOOLEAN},
             #{object.accessWindowStart,jdbcType=TIME},
@@ -167,6 +173,7 @@
         UPDATE guacamole_user
         SET password_hash = #{object.passwordHash,jdbcType=BINARY},
             password_salt = #{object.passwordSalt,jdbcType=BINARY},
+            password_date = #{object.passwordDate,jdbcType=TIMESTAMP},
             disabled = #{object.disabled,jdbcType=BOOLEAN},
             expired = #{object.expired,jdbcType=BOOLEAN},
             access_window_start = #{object.accessWindowStart,jdbcType=TIME},

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql
index 4f780c1..e308dce 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/001-create-schema.sql
@@ -126,6 +126,7 @@ CREATE TABLE guacamole_user (
   username      varchar(128) NOT NULL,
   password_hash bytea        NOT NULL,
   password_salt bytea,
+  password_date timestamptz  NOT NULL DEFAULT CURRENT_TIMESTAMP,
 
   -- Account disabled/expired status
   disabled      boolean      NOT NULL DEFAULT FALSE,

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.11.sql
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.11.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.11.sql
new file mode 100644
index 0000000..d2f430c
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.11.sql
@@ -0,0 +1,25 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you 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.
+--
+
+--
+-- Add per-user password set date
+--
+
+ALTER TABLE guacamole_user
+    ADD COLUMN password_date timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP;

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/a2074112/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
index 2bff4b9..39ec05a 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/user/UserMapper.xml
@@ -29,6 +29,7 @@
         <result column="username"            property="identifier"        jdbcType="VARCHAR"/>
         <result column="password_hash"       property="passwordHash"      jdbcType="BINARY"/>
         <result column="password_salt"       property="passwordSalt"      jdbcType="BINARY"/>
+        <result column="password_date"       property="passwordDate"      jdbcType="TIMESTAMP"/>
         <result column="disabled"            property="disabled"          jdbcType="BOOLEAN"/>
         <result column="expired"             property="expired"           jdbcType="BOOLEAN"/>
         <result column="access_window_start" property="accessWindowStart" jdbcType="TIME"/>
@@ -62,6 +63,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -86,6 +88,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -113,6 +116,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -140,6 +144,7 @@
             username,
             password_hash,
             password_salt,
+            password_date,
             disabled,
             expired,
             access_window_start,
@@ -152,6 +157,7 @@
             #{object.identifier,jdbcType=VARCHAR},
             #{object.passwordHash,jdbcType=BINARY},
             #{object.passwordSalt,jdbcType=BINARY},
+            #{object.passwordDate,jdbcType=TIMESTAMP},
             #{object.disabled,jdbcType=BOOLEAN},
             #{object.expired,jdbcType=BOOLEAN},
             #{object.accessWindowStart,jdbcType=TIME},
@@ -168,6 +174,7 @@
         UPDATE guacamole_user
         SET password_hash = #{object.passwordHash,jdbcType=BINARY},
             password_salt = #{object.passwordSalt,jdbcType=BINARY},
+            password_date = #{object.passwordDate,jdbcType=TIMESTAMP},
             disabled = #{object.disabled,jdbcType=BOOLEAN},
             expired = #{object.expired,jdbcType=BOOLEAN},
             access_window_start = #{object.accessWindowStart,jdbcType=TIME},


[5/5] incubator-guacamole-client git commit: GUACAMOLE-36: Merge password aging support.

Posted by jm...@apache.org.
GUACAMOLE-36: Merge password aging support.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/102d52f0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/102d52f0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/102d52f0

Branch: refs/heads/master
Commit: 102d52f0f9b3a34d798515a6956dbe43648d57de
Parents: 5650285 5cd90b8
Author: James Muehlner <ja...@guac-dev.org>
Authored: Thu Jan 5 10:25:57 2017 -0800
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Thu Jan 5 10:25:57 2017 -0800

----------------------------------------------------------------------
 .../jdbc/JDBCAuthenticationProviderService.java |  9 ++-
 .../auth/jdbc/security/PasswordPolicy.java      | 30 +++++++
 .../jdbc/security/PasswordPolicyService.java    | 83 ++++++++++++++++++++
 .../security/PasswordTooYoungException.java     | 53 +++++++++++++
 .../guacamole/auth/jdbc/user/ModeledUser.java   | 31 ++++++++
 .../guacamole/auth/jdbc/user/UserModel.java     | 30 +++++++
 .../guacamole/auth/jdbc/user/UserService.java   | 10 ++-
 .../src/main/resources/translations/en.json     |  3 +-
 .../schema/001-create-schema.sql                |  1 +
 .../schema/upgrade/upgrade-pre-0.9.11.sql       | 25 ++++++
 .../auth/mysql/MySQLPasswordPolicy.java         | 36 +++++++++
 .../guacamole/auth/jdbc/user/UserMapper.xml     |  7 ++
 .../schema/001-create-schema.sql                |  1 +
 .../schema/upgrade/upgrade-pre-0.9.11.sql       | 25 ++++++
 .../postgresql/PostgreSQLPasswordPolicy.java    | 36 +++++++++
 .../guacamole/auth/jdbc/user/UserMapper.xml     |  7 ++
 16 files changed, 384 insertions(+), 3 deletions(-)
----------------------------------------------------------------------



[3/5] incubator-guacamole-client git commit: GUACAMOLE-36: Implement password aging checks.

Posted by jm...@apache.org.
GUACAMOLE-36: Implement password aging checks.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/5f6fb8a1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/5f6fb8a1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/5f6fb8a1

Branch: refs/heads/master
Commit: 5f6fb8a1994206a85bd71b57b877fa24c630b7c3
Parents: a207411
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Aug 19 17:35:12 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Jan 5 06:30:40 2017 -0800

----------------------------------------------------------------------
 .../jdbc/JDBCAuthenticationProviderService.java |  9 ++-
 .../auth/jdbc/security/PasswordPolicy.java      | 30 +++++++
 .../jdbc/security/PasswordPolicyService.java    | 83 ++++++++++++++++++++
 .../security/PasswordTooYoungException.java     | 53 +++++++++++++
 .../guacamole/auth/jdbc/user/UserService.java   | 17 +++-
 .../src/main/resources/translations/en.json     |  3 +-
 .../auth/mysql/MySQLPasswordPolicy.java         | 36 +++++++++
 .../postgresql/PostgreSQLPasswordPolicy.java    | 36 +++++++++
 8 files changed, 264 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
index a0d422a..9839055 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
@@ -22,6 +22,7 @@ package org.apache.guacamole.auth.jdbc;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.auth.jdbc.security.PasswordPolicyService;
 import org.apache.guacamole.auth.jdbc.sharing.user.SharedAuthenticatedUser;
 import org.apache.guacamole.auth.jdbc.user.ModeledUser;
 import org.apache.guacamole.auth.jdbc.user.ModeledUserContext;
@@ -56,6 +57,12 @@ public class JDBCAuthenticationProviderService implements AuthenticationProvider
     private UserService userService;
 
     /**
+     * Service for enforcing password complexity policies.
+     */
+    @Inject
+    private PasswordPolicyService passwordPolicyService;
+
+    /**
      * Provider for retrieving UserContext instances.
      */
     @Inject
@@ -101,7 +108,7 @@ public class JDBCAuthenticationProviderService implements AuthenticationProvider
 
         // Update password if password is expired
         UserModel userModel = user.getModel();
-        if (userModel.isExpired())
+        if (userModel.isExpired() || passwordPolicyService.isPasswordExpired(userModel))
             userService.resetExpiredPassword(user, authenticatedUser.getCredentials());
 
         // Link to user context

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
index 8526bf6..eb02ba3 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
@@ -43,6 +43,36 @@ public interface PasswordPolicy {
     int getMinimumLength() throws GuacamoleException;
 
     /**
+     * Returns the minimum number of days which must elapse before the user's
+     * password may be reset. If this restriction does not apply, this will be
+     * zero.
+     *
+     * @return
+     *     The minimum number of days which must elapse before the user's
+     *     password must be reset, or zero if this restriction does not apply.
+     *
+     * @throws GuacamoleException
+     *     If the minimum password age cannot be parsed from
+     *     guacamole.properties.
+     */
+    int getMinimumAge() throws GuacamoleException;
+
+    /**
+     * Returns the maximum number of days which may elapse before the user's
+     * password must be reset. If this restriction does not apply, this will be
+     * zero.
+     *
+     * @return
+     *     The maximum number of days which may elapse before the user's
+     *     password must be reset, or zero if this restriction does not apply.
+     *
+     * @throws GuacamoleException
+     *     If the maximum password age cannot be parsed from
+     *     guacamole.properties.
+     */
+    int getMaximumAge() throws GuacamoleException;
+
+    /**
      * Returns whether both uppercase and lowercase characters must be present
      * in new passwords. If true, passwords which do not have at least one
      * uppercase letter and one lowercase letter cannot be used.

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
index 8d3c0b6..23fc367 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
@@ -20,10 +20,12 @@
 package org.apache.guacamole.auth.jdbc.security;
 
 import com.google.inject.Inject;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
+import org.apache.guacamole.auth.jdbc.user.UserModel;
 
 /**
  * Service which verifies compliance with the password policy configured via
@@ -146,4 +148,85 @@ public class PasswordPolicyService {
 
     }
 
+    /**
+     * Returns the age of the given user's password, in days. The age of a
+     * user's password is the amount of time elapsed since the password was last
+     * changed or reset.
+     *
+     * @param user
+     *     The user to calculate the password age of.
+     *
+     * @return
+     *     The age of the given user's password, in days.
+     */
+    private long getPasswordAge(UserModel user) {
+
+        // Pull both current time and the time the password was last reset
+        long currentTime = System.currentTimeMillis();
+        long lastResetTime = user.getPasswordDate().getTime();
+
+        // Calculate the number of days elapsed since the password was last reset
+        return TimeUnit.DAYS.convert(currentTime - lastResetTime, TimeUnit.MILLISECONDS);
+        
+    }
+
+    /**
+     * Verifies that the given user can change their password without violating
+     * password aging policy. If changing the user's password would violate the
+     * aging policy, a GuacamoleException will be thrown.
+     *
+     * @param user
+     *     The user whose password is changing.
+     *
+     * @throws GuacamoleException
+     *     If the user's password cannot be changed due to the password aging
+     *     policy, or of the password policy cannot be parsed from
+     *     guacamole.properties.
+     */
+    public void verifyPasswordAge(UserModel user) throws GuacamoleException {
+
+        // Retrieve password policy from environment
+        PasswordPolicy policy = environment.getPasswordPolicy();
+
+        long minimumAge = policy.getMinimumAge();
+        long passwordAge = getPasswordAge(user);
+
+        // Require that sufficient time has elapsed before allowing the password
+        // to be changed
+        if (passwordAge < minimumAge)
+            throw new PasswordTooYoungException("Password was already recently changed.",
+                    minimumAge - passwordAge);
+
+    }
+
+    /**
+     * Returns whether the given user's password is expired due to the password
+     * aging policy.
+     *
+     * @param user
+     *     The user to check.
+     *
+     * @return
+     *     true if the user needs to change their password to comply with the
+     *     password aging policy, false otherwise.
+     *
+     * @throws GuacamoleException
+     *     If the password policy cannot be parsed.
+     */
+    public boolean isPasswordExpired(UserModel user)
+            throws GuacamoleException {
+
+        // Retrieve password policy from environment
+        PasswordPolicy policy = environment.getPasswordPolicy();
+
+        // There is no maximum password age if 0
+        int maxPasswordAge = policy.getMaximumAge();
+        if (maxPasswordAge == 0)
+            return false;
+
+        // Determine whether password is expired based on maximum age
+        return getPasswordAge(user) >= maxPasswordAge;
+
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordTooYoungException.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordTooYoungException.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordTooYoungException.java
new file mode 100644
index 0000000..a5235dc
--- /dev/null
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordTooYoungException.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.guacamole.auth.jdbc.security;
+
+import java.util.Collections;
+import org.apache.guacamole.language.TranslatableMessage;
+
+/**
+ * Thrown when an attempt is made to set a user's password before sufficient
+ * time has elapsed since the password was last reset, in violation of the
+ * defined password policy.
+ *
+ * @author Michael Jumper
+ */
+public class PasswordTooYoungException extends PasswordPolicyException {
+
+    /**
+     * Creates a new PasswordTooYoungException with the given human-readable
+     * message. The translatable message is already defined.
+     *
+     * @param message
+     *     A human-readable message describing the password policy violation
+     *     that occurred.
+     *
+     * @param wait
+     *     The number of days the user should wait before attempting to reset
+     *     the password again.
+     */
+    public PasswordTooYoungException(String message, long wait) {
+        super(message, new TranslatableMessage(
+            "PASSWORD_POLICY.ERROR_TOO_YOUNG",
+            Collections.singletonMap("WAIT", wait)
+        ));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
index e131841..25dfa32 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
@@ -21,6 +21,7 @@ package org.apache.guacamole.auth.jdbc.user;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -210,6 +211,9 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
         if (object.getPassword() != null)
             passwordPolicyService.verifyPassword(object.getIdentifier(), object.getPassword());
 
+        // Update password reset date
+        model.setPasswordDate(new Timestamp(System.currentTimeMillis()));
+
     }
 
     @Override
@@ -233,9 +237,20 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
         }
 
         // Verify new password does not violate defined policies (if specified)
-        if (object.getPassword() != null)
+        if (object.getPassword() != null) {
+
+            // Enforce password age only for non-adminstrators
+            if (!user.getUser().isAdministrator())
+                passwordPolicyService.verifyPasswordAge(model);
+
+            // Always verify password complexity
             passwordPolicyService.verifyPassword(object.getIdentifier(), object.getPassword());
 
+            // Update password reset date
+            model.setPasswordDate(new Timestamp(System.currentTimeMillis()));
+
+        }
+
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json
index 3ee983f..95bb59b 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json
@@ -60,7 +60,8 @@
         "ERROR_REQUIRES_DIGIT"         : "Passwords must contain at least one digit.",
         "ERROR_REQUIRES_MULTIPLE_CASE" : "Passwords must contain both uppercase and lowercase characters.",
         "ERROR_REQUIRES_NON_ALNUM"     : "Passwords must contain at least one symbol.",
-        "ERROR_TOO_SHORT"              : "Passwords must be at least {LENGTH} {LENGTH, plural, one{character} other{characters}} long."
+        "ERROR_TOO_SHORT"              : "Passwords must be at least {LENGTH} {LENGTH, plural, one{character} other{characters}} long.",
+        "ERROR_TOO_YOUNG"              : "The password for this account has already been reset. Please wait at least {WAIT} more {WAIT, plural, one{day} other{days}} before changing the password again."
 
     },
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLPasswordPolicy.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLPasswordPolicy.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLPasswordPolicy.java
index 3d1ca71..0ee686c 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLPasswordPolicy.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLPasswordPolicy.java
@@ -46,6 +46,32 @@ public class MySQLPasswordPolicy implements PasswordPolicy {
     };
 
     /**
+     * The property which specifies the minimum number of days which must
+     * elapse before a user may reset their password. If set to zero, the
+     * default, then this restriction does not apply.
+     */
+    private static final IntegerGuacamoleProperty MIN_AGE =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "mysql-user-password-min-age"; }
+
+    };
+
+    /**
+     * The property which specifies the maximum number of days which may
+     * elapse before a user is required to reset their password. If set to zero,
+     * the default, then this restriction does not apply.
+     */
+    private static final IntegerGuacamoleProperty MAX_AGE =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "mysql-user-password-max-age"; }
+
+    };
+
+    /**
      * The property which specifies whether all user passwords must have at
      * least one lowercase character and one uppercase character. By default,
      * no such restriction is imposed.
@@ -120,6 +146,16 @@ public class MySQLPasswordPolicy implements PasswordPolicy {
     }
 
     @Override
+    public int getMinimumAge() throws GuacamoleException {
+        return environment.getProperty(MIN_AGE, 0);
+    }
+
+    @Override
+    public int getMaximumAge() throws GuacamoleException {
+        return environment.getProperty(MAX_AGE, 0);
+    }
+
+    @Override
     public boolean isMultipleCaseRequired() throws GuacamoleException {
         return environment.getProperty(REQUIRE_MULTIPLE_CASE, false);
     }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5f6fb8a1/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLPasswordPolicy.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLPasswordPolicy.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLPasswordPolicy.java
index adbee2a..002c96b 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLPasswordPolicy.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLPasswordPolicy.java
@@ -46,6 +46,32 @@ public class PostgreSQLPasswordPolicy implements PasswordPolicy {
     };
 
     /**
+     * The property which specifies the minimum number of days which must
+     * elapse before a user may reset their password. If set to zero, the
+     * default, then this restriction does not apply.
+     */
+    private static final IntegerGuacamoleProperty MIN_AGE =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "postgresql-user-password-min-age"; }
+
+    };
+
+    /**
+     * The property which specifies the maximum number of days which may
+     * elapse before a user is required to reset their password. If set to zero,
+     * the default, then this restriction does not apply.
+     */
+    private static final IntegerGuacamoleProperty MAX_AGE =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "postgresql-user-password-max-age"; }
+
+    };
+
+    /**
      * The property which specifies whether all user passwords must have at
      * least one lowercase character and one uppercase character. By default,
      * no such restriction is imposed.
@@ -120,6 +146,16 @@ public class PostgreSQLPasswordPolicy implements PasswordPolicy {
     }
 
     @Override
+    public int getMinimumAge() throws GuacamoleException {
+        return environment.getProperty(MIN_AGE, 0);
+    }
+
+    @Override
+    public int getMaximumAge() throws GuacamoleException {
+        return environment.getProperty(MAX_AGE, 0);
+    }
+
+    @Override
     public boolean isMultipleCaseRequired() throws GuacamoleException {
         return environment.getProperty(REQUIRE_MULTIPLE_CASE, false);
     }


[2/5] incubator-guacamole-client git commit: GUACAMOLE-36: Automatically update password date. Store previous date for comparison.

Posted by jm...@apache.org.
GUACAMOLE-36: Automatically update password date. Store previous date for comparison.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/80b80655
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/80b80655
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/80b80655

Branch: refs/heads/master
Commit: 80b80655cf734e6bf13901654e58ae4ccdf7346b
Parents: 5f6fb8a
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Aug 22 14:56:39 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Jan 5 06:30:40 2017 -0800

----------------------------------------------------------------------
 .../jdbc/JDBCAuthenticationProviderService.java |  2 +-
 .../jdbc/security/PasswordPolicyService.java    | 10 +++----
 .../guacamole/auth/jdbc/user/ModeledUser.java   | 31 ++++++++++++++++++++
 .../guacamole/auth/jdbc/user/UserService.java   |  9 +-----
 4 files changed, 38 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/80b80655/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
index 9839055..48fdf97 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
@@ -108,7 +108,7 @@ public class JDBCAuthenticationProviderService implements AuthenticationProvider
 
         // Update password if password is expired
         UserModel userModel = user.getModel();
-        if (userModel.isExpired() || passwordPolicyService.isPasswordExpired(userModel))
+        if (userModel.isExpired() || passwordPolicyService.isPasswordExpired(user))
             userService.resetExpiredPassword(user, authenticatedUser.getCredentials());
 
         // Link to user context

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/80b80655/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
index 23fc367..a47c038 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicyService.java
@@ -25,7 +25,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
-import org.apache.guacamole.auth.jdbc.user.UserModel;
+import org.apache.guacamole.auth.jdbc.user.ModeledUser;
 
 /**
  * Service which verifies compliance with the password policy configured via
@@ -159,11 +159,11 @@ public class PasswordPolicyService {
      * @return
      *     The age of the given user's password, in days.
      */
-    private long getPasswordAge(UserModel user) {
+    private long getPasswordAge(ModeledUser user) {
 
         // Pull both current time and the time the password was last reset
         long currentTime = System.currentTimeMillis();
-        long lastResetTime = user.getPasswordDate().getTime();
+        long lastResetTime = user.getPreviousPasswordDate().getTime();
 
         // Calculate the number of days elapsed since the password was last reset
         return TimeUnit.DAYS.convert(currentTime - lastResetTime, TimeUnit.MILLISECONDS);
@@ -183,7 +183,7 @@ public class PasswordPolicyService {
      *     policy, or of the password policy cannot be parsed from
      *     guacamole.properties.
      */
-    public void verifyPasswordAge(UserModel user) throws GuacamoleException {
+    public void verifyPasswordAge(ModeledUser user) throws GuacamoleException {
 
         // Retrieve password policy from environment
         PasswordPolicy policy = environment.getPasswordPolicy();
@@ -213,7 +213,7 @@ public class PasswordPolicyService {
      * @throws GuacamoleException
      *     If the password policy cannot be parsed.
      */
-    public boolean isPasswordExpired(UserModel user)
+    public boolean isPasswordExpired(ModeledUser user)
             throws GuacamoleException {
 
         // Retrieve password policy from environment

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/80b80655/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java
index 1353415..2f1e583 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/ModeledUser.java
@@ -22,6 +22,7 @@ package org.apache.guacamole.auth.jdbc.user;
 import com.google.inject.Inject;
 import java.sql.Date;
 import java.sql.Time;
+import java.sql.Timestamp;
 import java.text.ParseException;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -186,6 +187,12 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
      * user was retrieved from the database, this will be null.
      */
     private String password = null;
+
+    /**
+     * The time and date that this user's password was previously set (prior to
+     * being queried). If the user is new, this will be null.
+     */
+    private Timestamp previousPasswordDate = null;
     
     /**
      * Creates a new, empty ModeledUser.
@@ -194,6 +201,12 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
     }
 
     @Override
+    public void setModel(UserModel model) {
+        super.setModel(model);
+        this.previousPasswordDate = model.getPasswordDate();
+    }
+
+    @Override
     public String getPassword() {
         return password;
     }
@@ -222,6 +235,24 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
             userModel.setPasswordHash(hash);
         }
 
+        userModel.setPasswordDate(new Timestamp(System.currentTimeMillis()));
+
+    }
+
+    /**
+     * Returns the time and date that this user's password was previously set.
+     * If the user is new, this will be null. Unlike getPasswordDate() of
+     * UserModel (which is updated automatically along with the password salt
+     * and hash whenever setPassword() is invoked), this value is unaffected by
+     * calls to setPassword(), and will always be the value stored in the
+     * database at the time this user was queried.
+     *
+     * @return
+     *     The time and date that this user's password was previously set, or
+     *     null if the user is new.
+     */
+    public Timestamp getPreviousPasswordDate() {
+        return previousPasswordDate;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/80b80655/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
index 25dfa32..5bfd665 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
@@ -21,7 +21,6 @@ package org.apache.guacamole.auth.jdbc.user;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -211,9 +210,6 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
         if (object.getPassword() != null)
             passwordPolicyService.verifyPassword(object.getIdentifier(), object.getPassword());
 
-        // Update password reset date
-        model.setPasswordDate(new Timestamp(System.currentTimeMillis()));
-
     }
 
     @Override
@@ -241,14 +237,11 @@ public class UserService extends ModeledDirectoryObjectService<ModeledUser, User
 
             // Enforce password age only for non-adminstrators
             if (!user.getUser().isAdministrator())
-                passwordPolicyService.verifyPasswordAge(model);
+                passwordPolicyService.verifyPasswordAge(object);
 
             // Always verify password complexity
             passwordPolicyService.verifyPassword(object.getIdentifier(), object.getPassword());
 
-            // Update password reset date
-            model.setPasswordDate(new Timestamp(System.currentTimeMillis()));
-
         }
 
     }


[4/5] incubator-guacamole-client git commit: GUACAMOLE-36: Correct description of minimum password age.

Posted by jm...@apache.org.
GUACAMOLE-36: Correct description of minimum password age.

Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/5cd90b85
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/5cd90b85
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/5cd90b85

Branch: refs/heads/master
Commit: 5cd90b85d4b0af96c66413f2d8d36e2742b66a57
Parents: 80b8065
Author: Michael Jumper <mj...@apache.org>
Authored: Thu Jan 5 10:07:56 2017 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Thu Jan 5 10:07:56 2017 -0800

----------------------------------------------------------------------
 .../org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/5cd90b85/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
index eb02ba3..8413b6a 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/security/PasswordPolicy.java
@@ -49,7 +49,7 @@ public interface PasswordPolicy {
      *
      * @return
      *     The minimum number of days which must elapse before the user's
-     *     password must be reset, or zero if this restriction does not apply.
+     *     password may be reset, or zero if this restriction does not apply.
      *
      * @throws GuacamoleException
      *     If the minimum password age cannot be parsed from