GUACAMOLE-905: Merge automatically resume AudioContext when recording starts.

diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/ConfigurationService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/ConfigurationService.java
index 588c60d..47597b9 100644
--- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/ConfigurationService.java
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/ConfigurationService.java
@@ -373,4 +373,23 @@
         );
     }
 
+    /**
+     * Returns whether the LDAP attribute used to enumerate members in a group
+     * specifies UID or DN.
+     *
+     * @return
+     *     The type of data contained in the LDAP attribute used to enumerate
+     *     members in a group, as configured in guacamole.properties
+     *
+     * @throws GuacamoleException
+     *     If guacamole.properties cannot be parsed.
+     */
+    public MemberAttributeType getMemberAttributeType()
+            throws GuacamoleException {
+        return environment.getProperty(
+            LDAPGuacamoleProperties.LDAP_MEMBER_ATTRIBUTE_TYPE,
+            MemberAttributeType.DN
+        );
+    }
+
 }
diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java
index e5f44f0..f10844a 100644
--- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/LDAPGuacamoleProperties.java
@@ -255,4 +255,16 @@
         public String getName() { return "ldap-member-attribute"; }
         
     };
+
+    /**
+     * Specify the type of data contained in 'ldap-member-attribute'
+     */
+    public static final MemberAttributeTypeProperty LDAP_MEMBER_ATTRIBUTE_TYPE =
+            new MemberAttributeTypeProperty() {
+
+        @Override
+        public String getName() { return "ldap-member-attribute-type"; }
+
+    };
+
 }
diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/MemberAttributeType.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/MemberAttributeType.java
new file mode 100644
index 0000000..9a09fa2
--- /dev/null
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/MemberAttributeType.java
@@ -0,0 +1,38 @@
+/*
+ * 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.ldap.conf;
+
+/**
+ * All possible means of describing membership within 
+ * LDAP group directory records.
+ */
+public enum MemberAttributeType {
+
+    /**
+     * group membership is specified by DN
+     */
+    DN,
+
+    /**
+     * group membership is specified by usercode
+     */
+    UID;
+
+}
diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/MemberAttributeTypeProperty.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/MemberAttributeTypeProperty.java
new file mode 100644
index 0000000..8d9627d
--- /dev/null
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/conf/MemberAttributeTypeProperty.java
@@ -0,0 +1,56 @@
+/*
+ * 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.ldap.conf;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleServerException;
+import org.apache.guacamole.properties.GuacamoleProperty;
+
+/**
+ * A GuacamoleProperty whose value is a MemberAttributeType. The possible
+ * strings "dn" or "uid" are mapped to their values as a MemberAttributeType
+ * enum.  Anything else results in a parse error.
+ */
+public abstract class MemberAttributeTypeProperty
+        implements GuacamoleProperty<MemberAttributeType> {
+
+    @Override
+    public MemberAttributeType parseValue(String value)
+            throws GuacamoleException {
+
+        // If no value provided, return null.
+        if (value == null)
+            return null;
+
+        // dn
+        if (value.equals("dn"))
+            return MemberAttributeType.DN;
+
+        // uid
+        if (value.equals("uid"))
+            return MemberAttributeType.UID;
+
+        // The provided value is not legal
+        throw new GuacamoleServerException("Member attribute type must be "
+                          + "one of \"dn\" or \"uid\".");
+
+    }
+
+}
diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/group/UserGroupService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/group/UserGroupService.java
index 0628006..66f4612 100644
--- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/group/UserGroupService.java
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/group/UserGroupService.java
@@ -35,6 +35,7 @@
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.apache.guacamole.auth.ldap.conf.ConfigurationService;
+import org.apache.guacamole.auth.ldap.conf.MemberAttributeType;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.auth.ldap.ObjectQueryService;
 import org.apache.guacamole.net.auth.UserGroup;
@@ -176,6 +177,37 @@
         if (groupBaseDN == null)
             return Collections.emptyList();
 
+        // memberAttribute specified in properties could contain DN or username 
+        MemberAttributeType memberAttributeType = confService.getMemberAttributeType();
+        String userIDorDN = userDN.toString();
+        if (memberAttributeType == MemberAttributeType.UID) {
+            // Retrieve user objects with userDN
+            List<Entry> userEntries = queryService.search(
+                ldapConnection,
+                userDN,
+                confService.getUserSearchFilter(),
+                0);
+            // ... there can surely only be one
+            if (userEntries.size() != 1)
+                logger.warn("user DN \"{}\" does not return unique value "
+                        + "and will be ignored", userDN.toString());
+            else {
+                // determine unique identifier for user
+                Entry userEntry = userEntries.get(0);
+                Collection<String> userAttributes = confService.getUsernameAttributes();
+                try {
+                    userIDorDN = queryService.getIdentifier(userEntry,
+                                         userAttributes);
+                }
+                catch (LdapInvalidAttributeValueException e) {
+                    logger.error("User group missing identifier: {}",
+                            e.getMessage());
+                    logger.debug("LDAP exception while getting "
+                            + "group identifier.", e);
+                }
+            }
+        }
+
         // Get all groups the user is a member of starting at the groupBaseDN,
         // excluding guacConfigGroups
         return queryService.search(
@@ -183,7 +215,7 @@
             groupBaseDN,
             getGroupSearchFilter(),
             Collections.singleton(confService.getMemberAttribute()),
-            userDN.toString()
+            userIDorDN
         );
 
     }