GUAC-800: Add support for disabling user accounts.

This commit is contained in:
Michael Jumper
2015-05-26 12:42:57 -07:00
parent b64c4f3b94
commit c8c12663b3
13 changed files with 162 additions and 16 deletions

View File

@@ -23,7 +23,10 @@
package org.glyptodon.guacamole.auth.jdbc.user;
import com.google.inject.Inject;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.glyptodon.guacamole.auth.jdbc.base.ModeledDirectoryObject;
import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
@@ -34,6 +37,7 @@ import org.glyptodon.guacamole.auth.jdbc.activeconnection.ActiveConnectionPermis
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionGroupPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.ConnectionPermissionService;
import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionService;
import org.glyptodon.guacamole.form.Field;
import org.glyptodon.guacamole.net.auth.User;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
@@ -47,6 +51,24 @@ import org.glyptodon.guacamole.net.auth.permission.SystemPermissionSet;
*/
public class ModeledUser extends ModeledDirectoryObject<UserModel> implements User {
/**
* The name of the attribute which controls whether a user account is
* disabled.
*/
public static final String DISABLED_ATTRIBUTE_NAME = "disabled";
/**
* A typed field corresponding to the disabled attribute of a user.
*/
public static final Field DISABLED_ATTRIBUTE = new Field(DISABLED_ATTRIBUTE_NAME, "Disabled", "true");
/**
* All possible attributes of user objects.
*/
public static final Collection<Field> ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList(
DISABLED_ATTRIBUTE
));
/**
* Service for hashing passwords.
*/
@@ -183,12 +205,21 @@ public class ModeledUser extends ModeledDirectoryObject<UserModel> implements Us
@Override
public Map<String, String> getAttributes() {
return Collections.<String, String>emptyMap();
Map<String, String> attributes = new HashMap<String, String>();
// Set disabled attribute
attributes.put("disabled", getModel().isDisabled() ? "true" : null);
return attributes;
}
@Override
public void setAttributes(Map<String, String> attributes) {
// Drop all attributes - none currently supported
// Translate disabled attribute
getModel().setDisabled("true".equals(attributes.get("disabled")));
}
}

View File

@@ -135,7 +135,7 @@ public class UserContext extends RestrictedObject
@Override
public Collection<Field> getUserAttributes() {
return Collections.<Field>emptyList();
return ModeledUser.ATTRIBUTES;
}
@Override

View File

@@ -67,7 +67,7 @@ public class UserContextService {
// Authenticate user
ModeledUser user = userService.retrieveUser(credentials);
if (user != null) {
if (user != null && !user.getModel().isDisabled()) {
// Upon successful authentication, return new user context
UserContext context = userContextProvider.get();

View File

@@ -42,6 +42,12 @@ public class UserModel extends ObjectModel {
*/
private byte[] passwordSalt;
/**
* Whether the user account is disabled. Disabled accounts exist and can
* be modified, but cannot be used.
*/
private boolean disabled;
/**
* Creates a new, empty user.
*/
@@ -97,4 +103,28 @@ public class UserModel extends ObjectModel {
this.passwordSalt = passwordSalt;
}
/**
* 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.
*
* @return
* true if the account is disabled, false otherwise.
*/
public boolean isDisabled() {
return disabled;
}
/**
* Sets whether the user is 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.
*
* @param disabled
* true if the account should be disabled, false otherwise.
*/
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
}

View File

@@ -0,0 +1,5 @@
{
"USER_ATTRIBUTES" : {
"FIELD_HEADER_DISABLED" : "Disabled:"
}
}

View File

@@ -76,6 +76,7 @@ CREATE TABLE `guacamole_user` (
`username` varchar(128) NOT NULL,
`password_hash` binary(32) NOT NULL,
`password_salt` binary(32),
`disabled` boolean NOT NULL DEFAULT 0,
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`)

View File

@@ -0,0 +1,28 @@
--
-- Copyright (C) 2015 Glyptodon LLC
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
--
--
-- Add per-user disable flag
--
ALTER TABLE guacamole_user ADD COLUMN disabled BOOLEAN NOT NULL DEFAULT 0;

View File

@@ -7,6 +7,10 @@
"authProviders" : [
"net.sourceforge.guacamole.net.auth.mysql.MySQLAuthenticationProvider"
],
"translations" : [
"translations/en_US.json"
]
}

View File

@@ -32,6 +32,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="disabled" property="disabled" jdbcType="BOOLEAN"/>
</resultMap>
<!-- Select all usernames -->
@@ -57,7 +58,8 @@
user_id,
username,
password_hash,
password_salt
password_salt,
disabled
FROM guacamole_user
WHERE username IN
<foreach collection="identifiers" item="identifier"
@@ -74,7 +76,8 @@
guacamole_user.user_id,
username,
password_hash,
password_salt
password_salt,
disabled
FROM guacamole_user
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
WHERE username IN
@@ -94,7 +97,8 @@
user_id,
username,
password_hash,
password_salt
password_salt,
disabled
FROM guacamole_user
WHERE
username = #{username,jdbcType=VARCHAR}
@@ -114,12 +118,14 @@
INSERT INTO guacamole_user (
username,
password_hash,
password_salt
password_salt,
disabled
)
VALUES (
#{object.identifier,jdbcType=VARCHAR},
#{object.passwordHash,jdbcType=BINARY},
#{object.passwordSalt,jdbcType=BINARY}
#{object.passwordSalt,jdbcType=BINARY},
#{object.disabled,jdbcType=BOOLEAN}
)
</insert>
@@ -128,7 +134,8 @@
<update id="update" parameterType="org.glyptodon.guacamole.auth.jdbc.user.UserModel">
UPDATE guacamole_user
SET password_hash = #{object.passwordHash,jdbcType=BINARY},
password_salt = #{object.passwordSalt,jdbcType=BINARY}
password_salt = #{object.passwordSalt,jdbcType=BINARY},
disabled = #{object.disabled,jdbcType=BOOLEAN}
WHERE user_id = #{object.objectID,jdbcType=VARCHAR}
</update>

View File

@@ -117,6 +117,7 @@ CREATE TABLE guacamole_user (
username varchar(128) NOT NULL,
password_hash bytea NOT NULL,
password_salt bytea,
disabled boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY (user_id),

View File

@@ -0,0 +1,28 @@
--
-- Copyright (C) 2015 Glyptodon LLC
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
--
--
-- Add per-user disable flag
--
ALTER TABLE guacamole_user ADD COLUMN disabled boolean NOT NULL DEFAULT FALSE;

View File

@@ -7,6 +7,10 @@
"authProviders" : [
"org.glyptodon.guacamole.auth.postgresql.PostgreSQLAuthenticationProvider"
],
"translations" : [
"translations/en_US.json"
]
}

View File

@@ -32,6 +32,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="disabled" property="disabled" jdbcType="BOOLEAN"/>
</resultMap>
<!-- Select all usernames -->
@@ -57,7 +58,8 @@
user_id,
username,
password_hash,
password_salt
password_salt,
disabled
FROM guacamole_user
WHERE username IN
<foreach collection="identifiers" item="identifier"
@@ -74,7 +76,8 @@
guacamole_user.user_id,
username,
password_hash,
password_salt
password_salt,
disabled
FROM guacamole_user
JOIN guacamole_user_permission ON affected_user_id = guacamole_user.user_id
WHERE username IN
@@ -94,7 +97,8 @@
user_id,
username,
password_hash,
password_salt
password_salt,
disabled
FROM guacamole_user
WHERE
username = #{username,jdbcType=VARCHAR}
@@ -114,12 +118,14 @@
INSERT INTO guacamole_user (
username,
password_hash,
password_salt
password_salt,
disabled
)
VALUES (
#{object.identifier,jdbcType=VARCHAR},
#{object.passwordHash,jdbcType=BINARY},
#{object.passwordSalt,jdbcType=BINARY}
#{object.passwordSalt,jdbcType=BINARY},
#{object.disabled,jdbcType=BOOLEAN}
)
</insert>
@@ -128,7 +134,8 @@
<update id="update" parameterType="org.glyptodon.guacamole.auth.jdbc.user.UserModel">
UPDATE guacamole_user
SET password_hash = #{object.passwordHash,jdbcType=BINARY},
password_salt = #{object.passwordSalt,jdbcType=BINARY}
password_salt = #{object.passwordSalt,jdbcType=BINARY},
disabled = #{object.disabled,jdbcType=BOOLEAN}
WHERE user_id = #{object.objectID,jdbcType=VARCHAR}
</update>