pycontribs / jira

Python Jira library. Development chat available on https://matrix.to/#/#pycontribs:matrix.org
https://jira.readthedocs.io
BSD 2-Clause "Simplified" License
1.91k stars 856 forks source link

add_user_to_group fails with cloud Jira sites #1361

Open scott-hpe opened 2 years ago

scott-hpe commented 2 years ago

Bug summary

When adding a user to group in Jira cloud it fails with 404 and stacktrace shown below. Possibly related to GDPR changes and username not being valid any more. Confirmed working when using curl example:

curl --request POST \
  --url 'https://site.atlassian.net/rest/api/3/group/user?groupname=jira-software-users' \
  --user '<username:<token>' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"accountId": "62577b089e7380006fb38d2c"}'

Is there an existing issue for this?

Jira Instance type

Jira Cloud (Hosted by Atlassian)

Jira instance version

No response

jira-python version

main

Python Interpreter version

3.10

Which operating systems have you used?

Reproduction steps

user = jira_conn.user(id='62577b089e7380006fb38d2c')
grp = jira_conn.group(id='jira-software-users')
print(user.raw)
print(grp.raw)
jira_conn.add_user_to_group(user.emailAddress, grp.name)

Stack trace

{'self': 'https://site.atlassian.net/rest/api/2/user?accountId=62577b089e7380006fb38d2c', 'accountId': '62577b089e7380006fb38d2c', 'accountType': 'atlassian', 'emailAddress': 'scottrus@site.com', 'avatarUrls': {'48x48': 'https://secure.gravatar.com/avatar/f8e077def6b790546ea295ad3cf9c26b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FS-2.png', '24x24': 'https://secure.gravatar.com/avatar/f8e077def6b790546ea295ad3cf9c26b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FS-2.png', '16x16': 'https://secure.gravatar.com/avatar/f8e077def6b790546ea295ad3cf9c26b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FS-2.png', '32x32': 'https://secure.gravatar.com/avatar/f8e077def6b790546ea295ad3cf9c26b?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FS-2.png'}, 'displayName': 'scottrus', 'active': True, 'timeZone': 'America/Los_Angeles', 'locale': 'en_US', 'groups': {'size': 0, 'items': []}, 'applicationRoles': {'size': 0, 'items': []}, 'expand': 'groups,applicationRoles'}
{'name': 'jira-software-users', 'groupId': '6c541bd9-640b-4fbc-8473-b28533d64955', 'self': 'https://site.atlassian.net/rest/api/2/group?groupId=6c541bd9-640b-4fbc-8473-b28533d64955', 'users': {'size': 1837, 'items': [], 'max-results': 50, 'start-index': 0, 'end-index': 0}, 'expand': 'users'}
Traceback (most recent call last):
  File "/Users/srussell/IdeaProjects/addAtlassianUser/userThing.py", line 49, in <module>
    jira_conn.add_user_to_group(user.emailAddress, grp.name)
  File "/Users/srussell/.asdf/installs/python/3.10.2/lib/python3.10/site-packages/jira/client.py", line 4405, in add_user_to_group
    r: Dict[str, Any] = json_loads(self._session.post(url, params=x, data=payload))
  File "/Users/srussell/.asdf/installs/python/3.10.2/lib/python3.10/site-packages/jira/resilientsession.py", line 198, in post
    return self.__verb("POST", str(url), data=data, json=json, **kwargs)
  File "/Users/srussell/.asdf/installs/python/3.10.2/lib/python3.10/site-packages/jira/resilientsession.py", line 189, in __verb
    raise_on_error(response, verb=verb, **kwargs)
  File "/Users/srussell/.asdf/installs/python/3.10.2/lib/python3.10/site-packages/jira/resilientsession.py", line 64, in raise_on_error
    raise JIRAError(
jira.exceptions.JIRAError: JiraError HTTP 404 url: https://site.atlassian.net/rest/api/latest/group/user?groupname=jira-software-users
    text: Specified user does not exist or you do not have required permissions

    response headers = {'Server': 'AtlassianProxy/1.19.3.1', 'cache-control': 'no-cache, no-store, no-transform', 'Content-Type': 'application/json;charset=UTF-8', 'content-encoding': 'gzip', 'Strict-Transport-Security': 'max-age=315360000; includeSubDomains; preload', 'Date': 'Fri, 15 Apr 2022 16:16:35 GMT', 'ATL-TraceId': '7d9e57aa147b673b', 'x-arequestid': '739af2a3-793b-42b4-ad72-03c9ad9ab760', 'x-aaccountid': '5c05799ad3af3b1ccfec7110', 'X-XSS-Protection': '1; mode=block', 'Transfer-Encoding': 'chunked', 'timing-allow-origin': '*', 'x-envoy-upstream-service-time': '38', 'X-Content-Type-Options': 'nosniff', 'Connection': 'keep-alive', 'Expect-CT': 'report-uri="https://web-security-reports.services.atlassian.com/expect-ct-report/global-proxy", enforce, max-age=86400'}
    response text = {"errorMessages":["Specified user does not exist or you do not have required permissions"],"errors":{}}

Process finished with exit code 1

Expected behaviour

User should be added to group.

Additional Context

No response

adehad commented 2 years ago

Thanks for the details! As you say this is definitely a bug on this side handling the GDPR change.

As an FYI, you would probably need to use jira_conn.add_user_to_group(user.accountId, grp.name) once we implement a fix that would look like this:

    def add_user_to_group(
        self, username: str, group: str
    ) -> Union[bool, Dict[str, Any]]:
        """Add a user to an existing group.

        Args:
            username (str): Username that will be added to specified group.
            group (str): Group that the user will be added to.

        Returns:
            Union[bool,Dict[str,Any]]: json response from Jira server for success or a value that evaluates as False in case of failure.
        """
        url = self._get_latest_url("group/user")
        x = {"groupname": group}
        y = {"accountId" if self._is_cloud else "name": username}

        payload = json.dumps(y)

        r: Dict[str, Any] = json_loads(self._session.post(url, params=x, data=payload))
        if "name" not in r or r["name"] != group:
            return False
        else:
            return r
trit3mio commented 2 years ago

The same error is being returned on trying to delete user from a group like this:

from jira.config import get_jira
from jira import JIRA

jira = get_jira(profile='enterprise-pro')

jira.remove_user_from_group('5e66020a1238f60cfe66ba98', 'advanced-roadmaps')

This is the error being returned:

PS C:\Users\pulgarig\Documents\JiraCloudREST> & c:/Users/pulgarig/Documents/JiraCloudREST/venv/Scripts/python.exe c:/Users/pulgarig/Documents/JiraCloudREST/jiralibrary.py Traceback (most recent call last): File "c:\Users\pulgarig\Documents\JiraCloudREST\jiralibrary.py", line 6, in jira.remove_user_from_group('5e66020a1238f60cfe66ba98', 'advanced-roadmaps') File "C:\Users\pulgarig\Documents\JiraCloudREST\venv\lib\site-packages\jira\client.py", line 4421, in remove_user_from_group self._session.delete(url, params=x) File "C:\Users\pulgarig\Documents\JiraCloudREST\venv\lib\site-packages\jira\resilientsession.py", line 204, in delete
return self.verb("DELETE", str(url), **kwargs) File "C:\Users\pulgarig\Documents\JiraCloudREST\venv\lib\site-packages\jira\resilientsession.py", line 189, in verb
raise_on_error(response, verb=verb, *kwargs) File "C:\Users\pulgarig\Documents\JiraCloudREST\venv\lib\site-packages\jira\resilientsession.py", line 64, in raise_on_error raise JIRAError( jira.exceptions.JIRAError: JiraError HTTP 404 url: https://vorwerk.atlassian.net/rest/api/latest/group/user?groupname=advanced-roadmaps&username=5e66020a1238f60cfe66ba98 text: Specified user does not exist or you do not have required permissions response headers = {'Date': 'Fri, 10 Jun 2022 12:17:56 GMT', 'Content-Type': 'application/json;charset=UTF-8', 'Server': 'globaledge-envoy', 'Timing-Allow-Origin': '', 'X-Arequestid': '0e0ebc88-f390-42fd-b78d-ffa4442d8f8e', 'X-Aaccountid': '60bf3808b1f93b0069603b4b', 'Cache-Control': 'no-cache, no-store, no-transform', 'Content-Encoding': 'gzip', 'X-Envoy-Upstream-Service-Time': '42', 'Expect-Ct': 'report-uri="https://web-security-reports.services.atlassian.com/expect-ct-report/atlassian-proxy", max-age=86400', 'Strict-Transport-Security': 'max-age=63072000; preload', 'X-Content-Type-Options': 'nosniff', 'X-Xss-Protection': '1; mode=block', 'Atl-Traceid': 'b3742f1570c7c0bc', 'Report-To': '{"group": "endpoint-1", "max_age": 600, "endpoints": [{"url": "https://dj9s4kmieytgz.cloudfront.net"}], "include_subdomains": true}', 'Nel': '{"report_to": "endpoint-1", "max_age": 600, "include_subdomains": true, "failure_fraction": 0.001}', 'Transfer-Encoding': 'chunked'} response text = {"errorMessages":["Specified user does not exist or you do not have required permissions"],"errors":{}}

beliaev-maksim commented 3 months ago

@adehad the fix you proposed works on our side. Can this code snippet be directly pushed to the package ?

kot0dama commented 3 months ago

+1 I can confirm this works as a patch to the module.

vahedashyan commented 3 months ago

+1, The patch worked for me too. Will it be in the next update? When is that coming out?

adehad commented 3 months ago

there is the possibility I can work on it this weekend, but happy to review/approve any PRs that might come before then. Glad to have confirmation the patch works, so I may implement it without a test (which was the main reason it isn't here already)