GUACAMOLE-770: Merge support for clearing TOTP data.

This commit is contained in:
Mike Jumper
2021-02-05 21:22:15 -08:00
committed by GitHub
4 changed files with 64 additions and 13 deletions

View File

@@ -19,8 +19,11 @@
package org.apache.guacamole.auth.totp.user;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.guacamole.form.BooleanField;
import org.apache.guacamole.form.Form;
import org.apache.guacamole.net.auth.DelegatingUser;
import org.apache.guacamole.net.auth.User;
@@ -40,7 +43,23 @@ public class TOTPUser extends DelegatingUser {
* confirmed by the user, and the user is thus fully enrolled.
*/
public static final String TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME = "guac-totp-key-confirmed";
/**
* The name of the field used to trigger a reset of the TOTP data.
*/
public static final String TOTP_KEY_SECRET_RESET_FIELD = "guac-totp-reset";
/**
* The form which contains all configurable properties for this user.
*/
public static final Form TOTP_CONFIG_FORM = new Form("totp-config-form",
Arrays.asList(
new BooleanField(TOTP_KEY_SECRET_RESET_FIELD, "true"),
new BooleanField(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME, "true")
)
);
/**
* Wraps the given User object, hiding and blocking access to the core
* attributes used by TOTP.
@@ -66,14 +85,19 @@ public class TOTPUser extends DelegatingUser {
public Map<String, String> getAttributes() {
// Create independent, mutable copy of attributes
Map<String, String> attributes =
new HashMap<String, String>(super.getAttributes());
Map<String, String> attributes = new HashMap<>(super.getAttributes());
// Protect the secret value by removing it
String secret = attributes.remove(TOTP_KEY_SECRET_ATTRIBUTE_NAME);
// If secret is null or empty, mark the reset as true.
if (secret == null || secret.isEmpty())
attributes.put(TOTP_KEY_SECRET_RESET_FIELD, "true");
// If secret has a value, mark the reset as false.
else
attributes.put(TOTP_KEY_SECRET_RESET_FIELD, "false");
// Do not expose any TOTP-related attributes outside this extension
attributes.remove(TOTP_KEY_SECRET_ATTRIBUTE_NAME);
attributes.remove(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME);
// Expose only non-TOTP attributes
return attributes;
}
@@ -82,13 +106,20 @@ public class TOTPUser extends DelegatingUser {
public void setAttributes(Map<String, String> attributes) {
// Create independent, mutable copy of attributes
attributes = new HashMap<String, String>(attributes);
// Do not expose any TOTP-related attributes outside this extension
attributes = new HashMap<>(attributes);
// Do not expose any TOTP secret attribute outside this extension
attributes.remove(TOTP_KEY_SECRET_ATTRIBUTE_NAME);
attributes.remove(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME);
// Pull off the boolean reset field
String reset = attributes.remove(TOTP_KEY_SECRET_RESET_FIELD);
// If reset has been set to true, clear the secret.
if (reset != null && reset.equals("true")) {
attributes.put(TOTP_KEY_SECRET_ATTRIBUTE_NAME, null);
attributes.put(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME, null);
}
// Set only non-TOTP attributes
super.setAttributes(attributes);
}

View File

@@ -19,7 +19,11 @@
package org.apache.guacamole.auth.totp.user;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.form.Form;
import org.apache.guacamole.net.auth.DecoratingDirectory;
import org.apache.guacamole.net.auth.DelegatingUserContext;
import org.apache.guacamole.net.auth.Directory;
@@ -60,5 +64,12 @@ public class TOTPUserContext extends DelegatingUserContext {
};
}
@Override
public Collection<Form> getUserAttributes() {
Collection<Form> userAttrs = new HashSet<>(super.getUserAttributes());
userAttrs.add(TOTPUser.TOTP_CONFIG_FORM);
return Collections.unmodifiableCollection(userAttrs);
}
}

View File

@@ -108,7 +108,7 @@ public class UserVerificationService {
// If no key is defined, attempt to generate a new key
String secret = attributes.get(TOTPUser.TOTP_KEY_SECRET_ATTRIBUTE_NAME);
if (secret == null) {
if (secret == null || secret.isEmpty()) {
// Generate random key for user
TOTPGenerator.Mode mode = confService.getMode();

View File

@@ -29,6 +29,15 @@
"SECTION_HEADER_DETAILS" : "Details:"
},
"USER_ATTRIBUTES" : {
"FIELD_HEADER_GUAC_TOTP_RESET" : "Clear TOTP secret:",
"FIELD_HEADER_GUAC_TOTP_KEY_CONFIRMED" : "TOTP key confirmed:",
"SECTION_HEADER_TOTP_CONFIG_FORM" : "Configure TOTP"
}
}