如何使用Http从Jira 4.4中删除附件

时间:2012-03-08 11:59:17

标签: jira

我一直在寻找一种使用SOAP Api从Jira中删除附件的方法,但似乎本身不可能这样做,我宁愿不必为Jira实现一个新的插件,如接受中所建议的那样回答this问题,或重新编译现有插件以支持here提及。

This对上述问题的回答似乎完全符合我的要求,但唉,我无法让我工作。我得到的回答是一个错误,说明:

  

XSRF安全令牌丢失

     

由于缺少表单令牌,JIRA无法完成此操作。

     

您可能已清除浏览器Cookie,这可能导致您当前的表单令牌过期。已重新发布新的表单令牌。

当我使用Asp.Net MVC C#时,我使用了答案中的代码,原样,只调整了服务器URL,以及不同的凭据(Jira用户)以及使用以下方式作为请求参数传递的用户名/密码:

os_username=jirausername&os_password=xxxxxxx

我目前使用的代码如下:

public void RemoveAttachment(string issueid, string attachmentid)
        {
            using (System.Net.WebClient client = new System.Net.WebClient())
            {
                //Compute jira server base url from WS url
                string baseUrl = _service.Url.Substring(0, _service.Url.IndexOf("/rpc/"));

                //Compute complete attachment url
                string attachmenturl = baseUrl + "/secure/DeleteAttachment.jspa?id=" +
                                       issueid + "&deleteAttachmentId=" + attachmentid;

                client.Credentials = new System.Net.NetworkCredential("jirausername", "xxxxxxx");
                string response = client.DownloadString(attachmenturl);
            }
    }

1 个答案:

答案 0 :(得分:0)

我最终使用的方法首先请求删除确认表单,然后从表单中提取所需的标记,最后发布与表单内容等效的内容以删除附件。代码如下。

public void RemoveAttachment(string issueid, string attachmentid)
{
    //Compute jira server base url from WS url
    string baseUrl = _service.Url.Substring(0, _service.Url.IndexOf("/rpc/"));

    //Compute complete attachment deletion confirm url
    string confirmurl = baseUrl + "/secure/DeleteAttachment!default.jspa?id=" +
                 issueid + "&deleteAttachmentId=" + attachmentid + "&os_username=jirauser&os_password=xxxxxx";

    //Create a cookie container to maintain the xsrf security token cookie.
    CookieContainer jiracontainer = new CookieContainer();

    //Create a get request for the page containing the delete confirmation.
    HttpWebRequest confirmrequest = (HttpWebRequest)WebRequest.Create(confirmurl);
    confirmrequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
    confirmrequest.CookieContainer = jiracontainer;

    //Get the response and the responsestream.
    WebResponse confirmdeleteresponse = confirmrequest.GetResponse();
    Stream ReceiveStream = confirmdeleteresponse.GetResponseStream();

    // Open the stream using a StreamReader for easy access.
    StreamReader confirmreader = new StreamReader(ReceiveStream);
    // Read the content.
    string confirmresponse = confirmreader.ReadToEnd();

    //Create a regex to extract the atl/xsrf token from a hidden field. (Might be nicer to read it from a cookie, which should also be possible).
    Regex atl_token_matcher = new Regex("<input[^>]*id=\"atl_token\"[^>]*value=\"(?<token>\\S+)\"[^>]*>", RegexOptions.Singleline);
    Match token_match = atl_token_matcher.Match(confirmresponse);

    if (token_match.Success)
    {
        //If we found the token get the value.
        string token = token_match.Groups["token"].Value;

        //Compute attachment delete url.
        string deleteurl = baseUrl + "/secure/DeleteAttachment.jspa";

        //Construct form data.
        string postdata = "atl_token=" + HttpContext.Current.Server.UrlEncode(token) + "&id=" + issueid + "&deleteAttachmentId=" + attachmentid + "&Delete=Delete&os_username=jirauser&os_password=xxxxxx";

        //Create a post request for the deletion page.
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(deleteurl);
        request.KeepAlive = false;
        request.CookieContainer = jiracontainer; // Remember to set the cookiecontainer.
        request.ProtocolVersion = HttpVersion.Version10;
        request.Method = "POST";

        //Turn our request string into a byte stream
        byte[] postBytes = Encoding.ASCII.GetBytes(postdata);

        //Make sure you specify the proper type.
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = postBytes.Length;
        Stream requestStream = request.GetRequestStream();

        //Send the post.
        requestStream.Write(postBytes, 0, postBytes.Length);
        requestStream.Close();

        //Get the response.
        WebResponse deleteresponse = request.GetResponse();

        // Open the responsestream using a StreamReader for easy access.
        StreamReader deleteresponsereader = new StreamReader(deleteresponse.GetResponseStream());

        // Read the content.
        string deleteresponsecontent = deleteresponsereader.ReadToEnd();

        // do whatever validation/reporting with the response...
    }
    else
    {
        //We couldn't find the atl_token. Throw an error or something...
    }

}

编辑: 同样的事情适用于删除评论。将'attachment'替换为'comment',将'deleteAttachmentId'替换为'commentId',你应该很高兴。