nyyManni / ejira

Emacs JIRA integration
GNU General Public License v3.0
255 stars 36 forks source link

I can unassign an issue but I can't assign it to a user or myself #37

Open AblatedSprocket opened 3 years ago

AblatedSprocket commented 3 years ago

Using the ejira-assign-issue command, I am able to mark an issue as Unassigned and it propagates to the server and updates back locally, but when I try to assign the issue to myself, I get the :ejira_assigned tag next to the issue indicating I'm the assignee, but the assignee property doesn't update and the server still says Unassigned. Also, when I try to assign the issue to a teammate, the assignee on the server is Unassigned. I don't think this is a permissions issue, I have admin rights to the project. There aren't any errors coming back from ejira. Any ideas on how to troubleshoot?

nyyManni commented 3 years ago

The first thing I would do is to try without ejira, using only jiralib2. Something like:

(jiralib2-assign-issue "<issue-key>" "<username>")

Maybe your jira server wants to have a different type of username, such as email address?

AblatedSprocket commented 3 years ago

That was a good idea, it did provide some insight. That request fails with this message: Request failed: invalid request: ((errorMessages 'accountId' must be the only user identifying query parameter in GDPR strict mode.) (errors)). To me, that means you're right, it wants a different type of username. Full name doesn't work which isn't too surprising, but email doesn't work either and i don't know what else Jira uses as an accountId.

nyyManni commented 3 years ago

The reason might be that jiralib2 is using the "name" -field to select the assignable user. Let's dig one layer deeper: use the jiralib2-session-call -function:

(jiralib2-session-call (format "/rest/api/2/issue/%s/assignee" "<issue-key>")
                       :type "PUT"
                       :data (json-encode '((key . "<username>")))))   ;; <-- see 'key' instead of 'name' here

The key-field is not necessarily the same as the name-field (allthough it is so on our JIRA instance) but you can figure it out for example via the assignable users api (open <jiralib2-url>/rest/api/2/user/assignable/search?issueKey=<issue-key> with a browser.), which should return you both.

Also, one of the reasons the email address did not work was that it got sent as a name-field instead of the emailAddress-field.

AblatedSprocket commented 3 years ago

Thanks for your suggestion, here's where I'm at. I'm able to get back user information from <jiralib2-url>/rest/api/2/user/assignable/search?issueKey=<issue-key>; I'm getting an accountId and some other information. After plugging the accountId for <username>and the issue key for <issue-key> into the jiralib2-session-call function I get nil back. The good news is that if the issue is assigned, the assignee is set to Unassigned like I was seeing earlier.

After some tinkering, I found this works:

(jiralib2-session-call (format "/rest/api/2/issue/%s/assignee" "<issue-key>")
                       :type "PUT"
                       :data (json-encode '((accountId . "<accountId>"))))
AblatedSprocket commented 3 years ago

Per the Jira API deprecation notice here, users can no longer be identified over the API by name, only by account ID. It looks like PR#24 on this repo and PR#6 on your jiralib2 repo address this deprecation. Is there anything preventing those PRs from being pushed through?

nyyManni commented 3 years ago

The jiralib2#6 has an open discussion pending. There has not been activity in months so maybe I will merge it with the modifications.

24 seems to have a FIXME for ejira-mention-user. Need to figure out how to handle that.

AblatedSprocket commented 3 years ago

Good to know, I did not see the discussion on jiralib2.

As for the FIXME, I'm not entirely sure what an inline-node is, but I did get mentioning users to work again using accountId. It's not very pretty, but it in the org file it looks like this: [[accountId:~<accountId>]].

I changed ejira--get-users:

(defun ejira--get-users ()
  "Fetch user list from server and cache it for the session."
  (or ejira--user-cache
      (setq ejira--user-cache
            (append
             '(("Unassigned" . ""))
             (remove nil
                     (mapcar (lambda (user)
                               (let ((name (decode-coding-string
                                            (cdr (assoc 'displayName user)) 'utf-8))
                                     (key (cdr (assoc 'accountId user))))
                                 (unless (s-starts-with? "#" key)
                                   (cons key name))))
                             (jiralib2-get-users (car ejira-projects))))))))

The only change is mapping the key to accountId instead of name. It might also be a good idea to swap the "" and "Unassigned" in the first key-value pair because the first entry for unassigned shows up blank as I C-. through items. If this function is only used in mentioning users, I suggest removing the Unassigned key-value pair altogether.

I then changed ejira-mention-user to this:

(defun ejira-mention-user ()
  "Insert a username link."
  (interactive)
  (let* ((jira-users (ejira--get-users))
         (fullname (completing-read "User: " (mapcar 'cdr jira-users)))
         (account-id (car (rassoc fullname jira-users))))
    (insert (format "[[accountId:~%s]]" account-id))))

The only change here is updating the format in the insert. These changes make mentioning users work again.

MadEarl commented 3 years ago

Problem as far as I recall was on the side of ox-jira, this one needs a fix as well to correctly convert the user from org to jira. I'm sorry I can't look into this right now ...

AblatedSprocket commented 3 years ago

That's ok. If the only issue is that mentioning users is broken, can we use something like what I'm proposing to get it working and deal with ox-jira in another PR? I don't know much about the nature of the FIXME so someone please let me know if I'm missing something.

MadEarl commented 3 years ago

I can look up the code change I made for ox-jira tomorrow, it's not much, and then it works in both directions. I've been using the code for months now without issues. The advantage is to then have a proper Org Link displaying the user's full name in the Org file and a working mention on the Jira side.

MadEarl commented 3 years ago

As I just had to modify one function, I put it in my .emacs instead of patching ox-jira:

(require 'ox-jira)

(defun ox-jira-link (link desc info)
  "Transcode a LINK object from Org to JIRA.
DESC is the description part of the link, or the empty string.
INFO is a plist holding contextual information.  See
`org-export-data'."
  (let* ((type (org-element-property :type link))
         (raw-path (org-element-property :path link))
         (desc (and (not (string= desc "")) desc))
         (path (cond
                ((member type '("http" "https" "ftp" "mailto" "doi"))
                 (concat type ":" raw-path))
                ((string-prefix-p "~accountid" raw-path)
                 raw-path)
                ((string= type "file")
                 (org-export-file-uri raw-path))
                ((string= type "custom-id")
                 (if desc (concat "#" desc) (concat "#" raw-path)))
                ((string-prefix-p "*" raw-path)
                 (concat "#" (seq-subseq raw-path 1)))
                (t raw-path))))
    (cond
     ;; Link with description
     ((and path desc) (format "[%s|%s]" desc path))
     ;; Link without description
     (path (format "[%s]" path))
     ;; Link with only description?!
     (t desc))))
AblatedSprocket commented 3 years ago

I'll test this. Do you mind if I look into a PR for this on ox-jira?

MadEarl commented 3 years ago

Certainly not, please go ahead, I was just too lazy to do it myself.

AblatedSprocket commented 3 years ago

Submitted PR to ox-jira, it's now in MELPA. I just tested this modified definition of ejira-mention-user and it works:

(defun ejira-mention-user ()
  "Insert a username link."
  (interactive)
  (let* ((jira-users (ejira--get-users2))
         (fullname (completing-read "User: " (mapcar 'cdr jira-users)))
         (account-id (car (rassoc fullname jira-users))))
    (insert (format "[[~accountId:%s][%s]]" account-id fullname))))

Would it be easier to amend MadEarl's pull request or should I create a new one?