private boolean setKey(UserContext context, UserTOTPKey key)
            throws GuacamoleException {

        // Get mutable set of attributes
        User self = context.self();
        Map<String, String> attributes = new HashMap<>();

        // Set/overwrite current TOTP key state
        attributes.put(TOTPUser.TOTP_KEY_SECRET_ATTRIBUTE_NAME, BASE32.encode(key.getSecret()));
        attributes.put(TOTPUser.TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME, key.isConfirmed() ? "true" : "false");
        self.setAttributes(attributes);

        // Confirm that attributes have actually been set
        Map<String, String> setAttributes = self.getAttributes();
        if (!setAttributes.containsKey(TOTPUser.TOTP_KEY_SECRET_ATTRIBUTE_NAME)
                || !setAttributes.containsKey(TOTPUser.TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME))
            return false;

        // Update user object
        try {
            context.getPrivileged().getUserDirectory().update(self);
        }
        catch (GuacamoleSecurityException e) {
            logger.info("User \"{}\" cannot store their TOTP key as they "
                    + "lack permission to update their own account and the "
                    + "TOTP extension was unable to obtain privileged access. "
                    + "TOTP will be disabled for this user.",
                    self.getIdentifier());
            logger.debug("Permission denied to set TOTP key of user "
                    + "account.", e);
            return false;
        }
        catch (GuacamoleUnsupportedException e) {
            logger.debug("Extension storage for user is explicitly read-only. "
                    + "Cannot update attributes to store TOTP key.", e);
            return false;
        }

        // TOTP key successfully stored/updated
        return true;

    }
Attempts to store the given TOTP key within the user account of the user
having the given UserContext. As not all extensions will support storage
of arbitrary attributes, this operation may fail.

@param context
    The UserContext associated with the user whose TOTP key is to be
    stored.

@param key
    The TOTP key to store.

@return
    true if the TOTP key was successfully stored, false if the extension
    handling storage does not support storage of the key.

@throws GuacamoleException
    If the extension handling storage fails internally while attempting
    to update the user.
extensions/guacamole-auth-totp/src/main/java/org/apache/guacamole/auth/totp/user/UserVerificationService.java