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

如何使用Http从Jira 4.4中删除附件,jira,Jira,我一直在寻找一种使用SOAP Api从Jira中删除附件的方法,但这似乎在本机上是不可能的,我更希望不必像问题的公认答案中所建议的那样为Jira实现一个新插件,或者像前面提到的那样重新编译现有插件以支持这一点 上述问题的答案似乎正是我想要的,但唉,我不能让我去工作。我得到的答复是一个错误,指出: XSRF安全令牌丢失 由于缺少表单令牌,JIRA无法完成此操作 您可能已清除浏览器cookies,这可能导致当前表单令牌过期。已重新发行新的表单令牌 由于我使用的是Asp.Net MVC#,因此我使用了

我一直在寻找一种使用SOAP Api从Jira中删除附件的方法,但这似乎在本机上是不可能的,我更希望不必像问题的公认答案中所建议的那样为Jira实现一个新插件,或者像前面提到的那样重新编译现有插件以支持这一点

上述问题的答案似乎正是我想要的,但唉,我不能让我去工作。我得到的答复是一个错误,指出:

XSRF安全令牌丢失

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

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

由于我使用的是Asp.Net MVC#,因此我使用了答案中的代码,只调整了服务器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);
            }
    }

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

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...
    }

}
public void RemoveAttachment(string issueid,string attachmentid)
{
//从WS-url计算jira服务器基url
字符串baseUrl=\u service.Url.Substring(0,\u service.Url.IndexOf(“/rpc/”);
//计算完整附件删除确认url
字符串confirmurl=baseUrl+“/secure/DeleteAttachment!default.jspa?id=”+
issueid+“&deleteAttachmentId=“+attachmentid+”&os_用户名=jirauser&os_密码=xxxxxx”;
//创建cookie容器以维护xsrf安全令牌cookie。
CookieContainer jiracontainer=新CookieContainer();
//为包含删除确认的页面创建get请求。
HttpWebRequest confirmrequest=(HttpWebRequest)WebRequest.Create(confirmurl);
confirmrequest.Credentials=System.Net.CredentialCache.DefaultCredentials;
confirmrequest.CookieContainer=jiracontainer;
//获取响应和responsestream。
WebResponse confirmdeleteresponse=confirmrequest.GetResponse();
Stream ReceiveStream=confirmdeleteresponse.GetResponseStream();
//使用StreamReader打开流以便于访问。
StreamReader confirmreader=新的StreamReader(ReceiveStream);
//阅读内容。
字符串confirmresponse=confirmreader.ReadToEnd();
//创建一个正则表达式,从隐藏字段中提取atl/xsrf令牌(从cookie中读取可能更好,这也是可能的)。
Regex-atl\u-token\u-matcher=new Regex(“]*id=\”atl\u-token\“[^>]*value=\”(?\\S+“[^>]*>”,RegexOptions.Singleline);
Match token\u Match=atl\u token\u matcher.Match(confirmresponse);
if(令牌匹配成功)
{
//如果我们找到了标记,就得到值。
string token=token_match.Groups[“token”].Value;
//计算附件删除url。
string deleteurl=baseUrl+“/secure/DeleteAttachment.jspa”;
//构造表单数据。
string postdata=“atl_token=“+HttpContext.Current.Server.UrlEncode(token)+”&id=“+issueid+”&deleteAttachmentId=“+attachmentid+”&Delete=Delete&os_username=jirauser&os_password=xxxxxx”;
//为删除页面创建post请求。
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(deleteurl);
request.KeepAlive=false;
request.CookieContainer=jiracontainer;//记住设置CookieContainer。
request.ProtocolVersion=HttpVersion.Version10;
request.Method=“POST”;
//将请求字符串转换为字节流
byte[]postBytes=Encoding.ASCII.GetBytes(postdata);
//确保指定了正确的类型。
request.ContentType=“application/x-www-form-urlencoded”;
request.ContentLength=postBytes.Length;
Stream requestStream=request.GetRequestStream();
//发邮件。
Write(postBytes,0,postBytes.Length);
requestStream.Close();
//得到回应。
WebResponse deleteresponse=request.GetResponse();
//使用StreamReader打开responsestream以便于访问。
StreamReader deleteresponsereader=新的StreamReader(deleteresponse.GetResponseStream());
//阅读内容。
字符串deleteresponsecontent=deleteresponsereader.ReadToEnd();
//对响应进行任何验证/报告。。。
}
其他的
{
//我们找不到atl_令牌。抛出错误或其他。。。
}
}
编辑:
同样的方法也适用于删除注释。将“attachment”替换为“comment”,将“deleteAttachmentId”替换为“commentId”,这样您就可以开始了。

在尝试删除附件之前,您是否执行了JIRA SOAP登录?i、 e.
jira\u token=jira\u object.login(用户名、密码)
。我不确定,但这可能会以某种方式创建安全令牌。另一件事要检查-你可以删除一个这样的附件使用网络界面?一些操作使用JIRA权限方案进行限制,其他操作需要管理员权限……我已经执行了登录,并尝试以几种方式使用令牌。我也已经有了适当的权限。但是感谢你的评论,我注意到删除确认页面的url是DeleteAttachment!default.jspa?atl_token=BSMT-K4U9-TEZ2-OYEI | a1427bcf5fd94ffb96c4634055a53a6c00af8b00 | lin&id=10598&deleteAttachmentId=10602(注意!default.jspa部分和token),这让我找到了一个解决方案。有关完整的解释,请参见下面的答案。您使用的是哪个版本?我认为atl#U令牌相对较新……我使用的是v4.0.1#471。恭喜你把它整理好了。