Repository: pycontribs/jira

Issue:
group_members fails missing emailAddress
Using Jira 6.4.8, there is no emailAddress returned for user in group_members call

See doc : https://docs.atlassian.com/jira/REST/6.4.8/#d2e4386

  File "/home/arnaud/git/qa-indicators/venv/lib/python2.7/site-packages/jira/client.py", line 681, in group_members
    result[user['name']] = {'fullname': user['displayName'], 'email': user['emailAddress'],
KeyError: u'emailAddress'
## <bountysource-plugin>

Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30456523-group_members-fails-missing-emailaddress?utm_campaign=plugin&utm_content=tracker%2F3650997&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F3650997&utm_medium=issues&utm_source=github).
</bountysource-plugin>



Discussion:
Unless you can post a JSON result from JIRA server that proves that it is possible to get a list of users that does not have the emailAddress for each user, I would have to close it as cannot reproduce.

In my case it did always included: self, name, key, emailAddress, avatarUrls, displayName, active and timeZone.

The 'users' parameter, which is default, tells it to expand the user details.

Hi,
Here is a shorten and anonymized json response from request : 
https://JIRASERVERjira/rest/api/2/group?groupname=GROUPNAME&expand=users

```
{
    "name": "GROUPNAME",
    "self": "https://JIRASERVER/jira/rest/api/2/group?groupname=bm-dev",
    "users":
    {
        "size": 17,
        "items":
        [
            {
                "self": "https://JIRASERVER/jira/rest/api/2/user?username=FIRST.LAST",
                "name": "FIRST.LAST",
                "key": "FIRST.LAST",
                "avatarUrls":
                {
                    "48x48": "https://JIRASERVER/jira/secure/useravatar?avatarId=10120",
                    "24x24": "https://JIRASERVER/jira/secure/useravatar?size=small&avatarId=10120",
                    "16x16": "https://JIRASERVER/jira/secure/useravatar?size=xsmall&avatarId=10120",
                    "32x32": "https://JIRASERVER/jira/secure/useravatar?size=medium&avatarId=10120"
                },
                "displayName": "FIRST LAST",
                "active": true,
                "timeZone": "Europe/Paris"
            },
            // same for all other users
        ],
        "max-results": 50,
        "start-index": 0,
        "end-index": 16
    },
    "expand": "users"
}
```


Resolving patch:
diff --git a/jira/client.py b/jira/client.py
--- a/jira/client.py
+++ b/jira/client.py
@@ -785,7 +785,7 @@ def group_members(self, group):
 
         result = {}
         for user in r['users']['items']:
-            result[user['name']] = {'fullname': user['displayName'], 'email': user['emailAddress'],
+            result[user['name']] = {'fullname': user['displayName'], 'email': user.get('emailAddress', 'hidden') ,
                                     'active': user['active']}
         return result
 
@@ -3108,6 +3108,28 @@ def rank(self, issue, next_issue):
             raise NotImplementedError('No API for ranking issues for agile_rest_path="%s"' %
                                       self._options['agile_rest_path'])
 
+    def move_to_backlog(self, issue_keys):
+        """
+        Move issues in ``issue_keys`` to the backlog, removing them from all
+        sprints that have not been completed.
+
+        :param issue_keys: the issues to move to the backlog
+        """
+
+        if self._options['agile_rest_path'] == GreenHopperResource.AGILE_BASE_REST_PATH:
+            url = self._get_url('backlog/issue', base=self.AGILE_BASE_URL)
+            payload = {'issues': issue_keys}
+            try:
+                self._session.post(url, data=json.dumps(payload))
+            except JIRAError as e:
+                if e.status_code == 404:
+                    warnings.warn('Status code 404 may mean, that too old JIRA Agile version is installed.'
+                                  ' At least version 6.7.10 is required.')
+                raise
+        else:
+            raise NotImplementedError('No API for moving issues to backlog for agile_rest_path="%s"' %
+                                      self._options['agile_rest_path'])
+
 
 class GreenHopper(JIRA):
 


Test patch: