jirarest2 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,25 @@
1
+ === 0.0.11 / 2012-08-05
2
+
3
+ * 1 major enhancements:
4
+
5
+ * Added support to authenticate with cookies (default with the scripts)
6
+
7
+ * 2 minor enhancements:
8
+
9
+ * Refactored Connect
10
+ * Refactored Credentials
11
+
12
+ * 1 bug fixes:
13
+
14
+ * fixed #7 It's now possible to use the scripts in (unix) pipes as well
15
+
16
+ * 3 unknowns:
17
+
18
+ * Added deb.rb to find debug information at compile stage (reacts to environment variable "DEBUG")
19
+ * Deleted deprecated files
20
+ * corrected spelling errors
21
+
22
+
1
23
  === 0.0.10 / 2012-08-02
2
24
 
3
25
  * 1 major enhancement:
@@ -4,18 +4,19 @@ History.txt
4
4
  Manifest.txt
5
5
  README.txt
6
6
  Rakefile
7
- bin/create_issue.rb
8
7
  bin/jira_comment
9
8
  bin/jira_create_issue
10
- bin/jira_create_issue.rb
11
9
  bin/jira_watcher
12
10
  copyright
11
+ lib/deb.rb
13
12
  lib/jirarest2.rb
14
13
  lib/jirarest2/connect.rb
14
+ lib/jirarest2/cookie_credentials.rb
15
15
  lib/jirarest2/credentials.rb
16
16
  lib/jirarest2/exceptions.rb
17
17
  lib/jirarest2/issue.rb
18
18
  lib/jirarest2/madbitconfig.rb
19
+ lib/jirarest2/password_credentials.rb
19
20
  lib/jirarest2/result.rb
20
21
  lib/jirarest2/services.rb
21
22
  lib/jirarest2/services/comment.rb
@@ -23,6 +24,7 @@ lib/jirarest2/services/issuelink.rb
23
24
  lib/jirarest2/services/issuelinktype.rb
24
25
  lib/jirarest2/services/watcher.rb
25
26
  lib/jirarest2bin.rb
27
+ test/data/cookiejar
26
28
  test/data/get-comments.txt
27
29
  test/data/issuespec.txt
28
30
  test/data/test.config.data
@@ -32,10 +34,12 @@ test/data/test.nojson1
32
34
  test/data/ticket.json
33
35
  test/test_comment.rb
34
36
  test/test_connect.rb
37
+ test/test_cookie_credentials.rb
35
38
  test/test_credentials.rb
36
39
  test/test_issue.rb
37
40
  test/test_issuelink.rb
38
41
  test/test_issuelinktype.rb
39
42
  test/test_madbitconfig.rb
43
+ test/test_password_credentials.rb
40
44
  test/test_result.rb
41
45
  test/test_watcher.rb
data/README.txt CHANGED
@@ -8,7 +8,7 @@ jirarest2 is yet another implementation of the JIRA(tm) REST-API[https://develop
8
8
 
9
9
  It is intended to be called within the shell to create and verify JIRA(tm) issues fast without a browser. There was no particular need for perfomance at the time of writing.
10
10
 
11
- This implementation is still a for cry from others like http://rubygems.org/gems/jira-ruby which requires oauth authentification.
11
+ This implementation is still a for cry from others like http://rubygems.org/gems/jira-ruby which requires oauth authentication.
12
12
 
13
13
  There are scripts to create new issues with watchers and link those to existing issues and to manipulate watchers on existing issues.
14
14
 
@@ -23,6 +23,7 @@ There are scripts to create new issues with watchers and link those to existing
23
23
  * jira_create_issue allows you to create new issues with watchers and link those to existing issues
24
24
  * jira_watcher allows you to manipulate watchers on existing issues
25
25
  * jira_comment allows you to add read and update comments. (The latter only if you know the right comment id)
26
+ * Uses cookie_auth by default. First login will be done via basic auth though.
26
27
 
27
28
  == SYNOPSIS:
28
29
 
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  require "jirarest2bin"
20
- require "pp"
20
+ require "deb"
21
21
 
22
22
  # Check for the minimum ruby version we need
23
23
  Jirarest2Bin::check_ruby_version
@@ -98,7 +98,7 @@ end
98
98
  # @param [Array] issues An Array containing the issuekeys
99
99
  # @param [Fixnum] id Identidication number of the comment to view
100
100
  def view_comments(issues,id = nil)
101
- connection = Jirarest2Bin::get_connection(@scriptopts,@connection)
101
+ connection = Jirarest2Bin::command(@scriptopts,@connection,:connection)
102
102
  result = Array.new
103
103
  if id.nil? then
104
104
  issues.each { |issue|
@@ -119,7 +119,7 @@ end
119
119
  # @param [String] method Kind of work to be done
120
120
  # @param [Fixnum] id Identifier of the comment
121
121
  def work(issues,text,method,id = nil)
122
- connection = Jirarest2Bin::get_connection(@scriptopts,@connection)
122
+ connection = Jirarest2Bin::command(@scriptopts,@connection,:connection)
123
123
  issues.each{ |issue|
124
124
  connectedissue = Comment.new(connection, issue, id)
125
125
  connectedissue.send method, text
@@ -18,7 +18,7 @@
18
18
  #
19
19
 
20
20
  require "jirarest2bin"
21
- require "pp"
21
+ require "deb"
22
22
 
23
23
  # Check for the minimum ruby version we need
24
24
  Jirarest2Bin::check_ruby_version
@@ -146,14 +146,7 @@ def open_issue
146
146
  if @issueopts.issue.nil? then
147
147
  Jirarest2Bin::required_argument("issue")
148
148
  end
149
- issue=Issue.new(@issueopts.project,@issueopts.issue,Jirarest2Bin::get_connection(@scriptopts,@connection))
150
- rescue Jirarest2::AuthentificationError => e
151
- puts "Password not accepted."
152
- @scriptopts.pass = Jirarest2Bin.get_password(@scriptopts.username)
153
- retry
154
- rescue Jirarest2::AuthentificationCaptchaError => e
155
- puts "Wrong Password too many times.\nCaptcha time at #{e.to_s} to reenable your account."
156
- exit 1
149
+ @connection,issue = Jirarest2Bin::command(@scriptopts,@connection,:issue,@issueopts.project,@issueopts.issue)
157
150
  rescue Jirarest2::WrongProjectException => e
158
151
  no_issue("project",e)
159
152
  rescue Jirarest2::WrongIssuetypeException => e
@@ -255,7 +248,9 @@ end
255
248
  =end
256
249
  def create_new_ticket(issue)
257
250
  begin
258
- connection = Jirarest2Bin::get_connection(@scriptopts,@connection) # We need it so often in the next few lines that I prefer to get the result in a variable
251
+ # connection = Jirarest2Bin::get_connection(@scriptopts,@connection) # We need it so often in the next few lines that I prefer to get the result in a variable
252
+ connection = Jirarest2Bin::command(@scriptopts,@connection,:connection)
253
+
259
254
  result = issue.persist(connection).result
260
255
  # Set the watchers
261
256
  if @issueopts.watchers then
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  require "jirarest2bin"
20
- require "pp"
20
+ require "deb"
21
21
 
22
22
  # Check for the minimum ruby version we need
23
23
  Jirarest2Bin::check_ruby_version
@@ -67,7 +67,7 @@ end # class
67
67
  # It will then print those issues and their watchers to STDOUT
68
68
  # @param [Array] issues An Array containing the issuekeys
69
69
  def view_watchers(issues)
70
- connection = Jirarest2Bin::get_connection(@scriptopts,@connection)
70
+ connection = Jirarest2Bin::command(@scriptopts,@connection,:connection)
71
71
  issues.each { |issue|
72
72
  connectedissue = Watcher.new(connection, issue)
73
73
  watchers = connectedissue.get_watchers
@@ -87,7 +87,7 @@ end
87
87
  # @param [Array] users Users to work with
88
88
  # @param [Array] toto Kind of work to be done
89
89
  def work_watchers(issues,users,todo)
90
- connection = Jirarest2Bin::get_connection(@scriptopts,@connection)
90
+ connection = Jirarest2Bin::command(@scriptopts,@connection,:connection)
91
91
  issues.each{ |issue|
92
92
  connectedissue = Watcher.new(connection, issue)
93
93
  method = todo + "_watcher" # the name of the method we want to call with send
@@ -1,6 +1,5 @@
1
- #!/usr/bin/env ruby
1
+ # This files only purpose is to have one place to control all debugging information
2
2
 
3
- # Script to create a new issue with jira.
4
3
  # Copyright (C) 2012 Cyril Bitterich
5
4
  #
6
5
  # This program is free software: you can redistribute it and/or modify
@@ -17,7 +16,12 @@
17
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
17
  #
19
18
 
20
- puts "File has been renamed to jira_create_issue"
21
- newfile = File.dirname($0) + "/jira_create_issue"
22
- puts "Please use: #{newfile} #{$*.join(" ")}"
23
19
 
20
+ if ENV['DEBUG'] then
21
+ require "pp"
22
+ # Version of pp that will result in errors if the environment Variable "DEBUG" is not set.
23
+ # A way to find forgotten debug info before shipping?
24
+ def ppp(data)
25
+ pp data
26
+ end
27
+ end
@@ -1,4 +1,4 @@
1
- # Jirarest2 is a gem to connect to the REST interface of JIRA(tm) . It uses Basic authentification and not oauth
1
+ # Jirarest2 is a gem to connect to the REST interface of JIRA(tm) . It uses Basic authentication and not oauth
2
2
 
3
3
 
4
4
  # Copyright (C) 2012 Cyril Bitterich
@@ -17,11 +17,13 @@
17
17
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- VERSION = "0.0.10"
20
+ VERSION = "0.0.11"
21
21
 
22
22
  require_relative "jirarest2/connect"
23
23
  require_relative "jirarest2/issue"
24
24
  require_relative "jirarest2/credentials"
25
+ require_relative "jirarest2/password_credentials"
26
+ require_relative "jirarest2/cookie_credentials"
25
27
  require_relative "jirarest2/exceptions"
26
28
  require_relative "jirarest2/services/watcher"
27
29
  require_relative "jirarest2/services"
@@ -19,31 +19,31 @@
19
19
  require 'net/http'
20
20
  require 'jirarest2/exceptions'
21
21
  require 'jirarest2/result'
22
- require "pp"
22
+ require "deb"
23
23
 
24
24
 
25
25
 
26
26
  # A Connect object encasulates the connection to jira via REST. It takes an Credentials object and returns a Jirarest2::Result object or an exception if something went wrong.
27
27
  class Connect
28
-
29
- # Create an instance of Connect.
30
- # @param [Credentials] credentials
28
+ # Get the credentials
29
+ attr_reader :credentials
30
+
31
+ # Create an instance of Connect.
32
+ # @param [Credentials] credentials
31
33
  def initialize(credentials)
32
- @pass = credentials.password
33
- @user = credentials.username
34
- @CONNECTURL = credentials.connecturl
34
+ @credentials = credentials
35
35
  end
36
36
 
37
37
 
38
38
 
39
- # Execute the request
40
- # @param [String, "Get", "Post", "Delete", "Put"] operation HTTP method: GET, POST, DELETE, PUT
41
- # @param [String] uritail The last part of the REST URI
42
- # @param [Hash] data Data to be sent.
43
- # @return [Jirarest2::Result]
39
+ # Execute the request
40
+ # @param [String, "Get", "Post", "Delete", "Put"] operation HTTP method: GET, POST, DELETE, PUT
41
+ # @param [String] uritail The last part of the REST URI
42
+ # @param [Hash] data Data to be sent.
43
+ # @return [Jirarest2::Result]
44
44
  def execute(operation,uritail,data)
45
45
  uri = nil
46
- uri = URI(@CONNECTURL+uritail)
46
+ uri = URI(@credentials.connecturl+uritail)
47
47
  if data != "" then
48
48
  if ! (operation == "Post" || operation == "Put") then # POST carries the payload in the body that's why we have to wait
49
49
  uri.query = URI.encode_www_form(data)
@@ -51,8 +51,10 @@ class Connect
51
51
  end
52
52
 
53
53
  req = nil
54
- req = Net::HTTP::const_get(operation).new(uri.request_uri) # "Classes Are Just Obejects, Too" (Design Patterns in Ruby, Russ Olsen, Addison Wessley)
55
- req.basic_auth @user, @pass
54
+ req = Net::HTTP::const_get(operation).new(uri.request_uri)
55
+ # Authentication Header is built up in a credential class
56
+ @credentials.get_auth_header(req)
57
+
56
58
  req["Content-Type"] = "application/json;charset=UTF-8"
57
59
 
58
60
  if data != "" then
@@ -67,16 +69,21 @@ class Connect
67
69
  result = Net::HTTP.start(uri.host, uri.port) {|http|
68
70
  http.request(req)
69
71
  }
70
-
71
72
  # deal with output
72
73
  case result
73
74
  when Net::HTTPBadRequest # 400
74
75
  raise Jirarest2::BadRequestError, result.body
75
76
  when Net::HTTPUnauthorized # 401 No login-credentials oder wrong ones.
76
- raise Jirarest2::AuthentificationError, result.body
77
+ if @credentials.instance_of?(PasswordCredentials) then
78
+ raise Jirarest2::PasswordAuthenticationError, result.body
79
+ elsif @credentials.instance_of?(CookieCredentials) then
80
+ raise Jirarest2::CookieAuthenticationError, result.body
81
+ else
82
+ raise Jirarest2::AuthenticationError, result.body
83
+ end
77
84
  when Net::HTTPForbidden # 403
78
85
  if result.get_fields("x-authentication-denied-reason")[0] =~ /.*login-url=(.*)/ then #Captcha-Time
79
- raise Jirarest2::AuthentificationCaptchaError, $1
86
+ raise Jirarest2::AuthenticationCaptchaError, $1
80
87
  else
81
88
  raise Jirarest2::ForbiddenError, result.body
82
89
  end
@@ -84,30 +91,29 @@ class Connect
84
91
  raise Jirarest2::NotFoundError, result.body
85
92
 
86
93
  end
87
-
88
- return Jirarest2::Result.new(result)
94
+ ret = Jirarest2::Result.new(result)
95
+ @credentials.bake_cookies(ret.header["set.cookie"]) if @credentials.instance_of?(CookieCredentials) # Make sure cookies are always up to date if we use them.
96
+ return ret
89
97
  end # execute
90
98
 
91
99
 
92
- # Is the rest API really at the destination we think it is?
93
- # @return [Boolean]
100
+ # Is the rest API really at the destination we think it is?
101
+ # @return [Boolean]
94
102
  def check_uri
95
- begin
96
- begin
97
- ret = (execute("Get","dashboard","").code == "200")
98
- # TODO is the 404 really possible?
99
- rescue Jirarest2::NotFoundError
100
- return false
101
- rescue Jirarest2::BadRequestError
102
- return false
103
- end
103
+ begin
104
+ ret = (execute("Get","dashboard","").code == "200")
105
+ # TODO is the 404 really possible?
106
+ rescue Jirarest2::NotFoundError
107
+ return false
108
+ rescue Jirarest2::BadRequestError
109
+ return false
104
110
  end
105
111
  end
106
112
 
107
- # Try to be nice. Parse the URI and see if you can find a pattern to the problem
108
- # @param [String] url
109
- # @return [String] a fixed URL
110
- def heal_uri(url = @CONNECTURL)
113
+ # Try to be nice. Parse the URI and see if you can find a pattern to the problem
114
+ # @param [String] url
115
+ # @return [String] a fixed URL
116
+ def heal_uri(url = @credentials.connecturl)
111
117
  splitURI = URI.split(url) # [Scheme,Userinfo,Host,Port,Registry,Path,Opaque,Query,Fragment]
112
118
  splitURI[5].gsub!(/^(.*)2$/,'\12/')
113
119
  splitURI[5].gsub!(/\/+/,'/') # get rid of duplicate /
@@ -123,16 +129,16 @@ class Connect
123
129
  end
124
130
 
125
131
 
126
- # try to fix the connecturl of this instance
127
- # @return [String,Jirarest2::CouldNotHealURIError] Fixed URL or Exception
132
+ # try to fix the connecturl of this instance
133
+ # @return [String,Jirarest2::CouldNotHealURIError] Fixed URL or Exception
128
134
  def heal_uri!
129
135
  if ! check_uri then
130
- @CONNECTURL = heal_uri(@CONNECTURL)
136
+ @credentials.connecturl = heal_uri(@credentials.connecturl)
131
137
  end
132
138
  if check_uri then
133
- return @CONNECTURL
139
+ return @credentials.connecturl
134
140
  else
135
- raise Jirarest2::CouldNotHealURIError, @CONNECTURL
141
+ raise Jirarest2::CouldNotHealURIError, @credentials.connecturl
136
142
  end
137
143
  end
138
144
 
@@ -0,0 +1,126 @@
1
+ # Copyright (C) 2012 Cyril Bitterich
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+ #
16
+
17
+ require_relative "credentials"
18
+ require_relative "password_credentials"
19
+ require_relative "result"
20
+ require_relative "connect"
21
+ require "pstore"
22
+
23
+ # Cookies as credential for the server
24
+ # login uses basic auth to log in and then cookies are used
25
+ class CookieCredentials < Credentials
26
+
27
+ # Location of the file the cookie is persited on a harddrive. Default is "~/.jirarest2.cookie
28
+ attr_accessor :cookiestore
29
+
30
+ # @param [String] url URL to JIRA(tm) instance
31
+ # @param [Boolean] autosave Save the cookie on the harddisk whenever something happens?
32
+ def initialize(connecturl, autosave = false )
33
+ super(connecturl)
34
+ @cookiejar = {}
35
+ @autosave = autosave
36
+ @cookiestore = "~/.jirarest2.cookie"
37
+ end
38
+
39
+ # Setup new cookies or update the existing jar.
40
+ # @param [Array] header Header after a request
41
+ def bake_cookies(header)
42
+ return if !header
43
+ header.each do |cookie|
44
+ next unless (pair = cookie.gsub(/[;]*\s*Path=\S+[,]*/,'').split(/\=/)).length == 2
45
+ @cookiejar[pair.first] = pair.last
46
+ end
47
+ store_cookiejar if @autosave
48
+ return @cookiejar
49
+ end
50
+
51
+ # Name alias for bake_cookies
52
+ # @param [String] header Header after a request
53
+ def set_cookies(header)
54
+ return bake_cookies(header)
55
+ end
56
+
57
+ # Get the cookies in the format to send as header
58
+ def get_cookies
59
+ @cookiejar.map { |cookie| cookie * '=' }.join('; ')
60
+ end
61
+
62
+ # Get the auth header to send to the server
63
+ # @param [Net:::HTTP::Post,Net:::HTTP::Put,Net:::HTTP::Get,Net:::HTTP::Delete] request Request object
64
+ # @raise [Jirarest2::AuthenticationError] if there is no JSESSIONID cookie entry
65
+ # @return [String] Header-Line
66
+ def get_auth_header(request)
67
+ if @cookiejar["JSESSIONID"].nil? then
68
+ raise Jirarest2::CookieAuthenticationError, "No valid cookies"
69
+ end
70
+ if get_cookies == "" then
71
+ # This code should never be executed as the AuthenticationError above will catch more cases
72
+ request["Cookie"] = "JSESSIONID=0"
73
+ else
74
+ request["Cookie"] = get_cookies
75
+ end
76
+ end
77
+
78
+ # Login per username and password in case the cookie is invalid or missing
79
+ # Uses basic auth to authenticate
80
+ # @param [String] username Username to use for login
81
+ # @param [String] password Password to use for login
82
+ def login(username,password)
83
+ pconnecturl = @connecturl.gsub(/\/*rest\/api\/.+/,"/rest/") # Unfortunately the session information is not in the same tree as all the other rest calls
84
+ pcred = PasswordCredentials.new(pconnecturl,username,password)
85
+ pconnect = Connect.new(pcred)
86
+ result = pconnect.execute("Post","auth/latest/session",{"username" => username, "password" => password})
87
+ bake_cookies(result.header["set-cookie"]) # I already had them seperated into an Array.
88
+ return @cookiejar["JSESSIONID"]
89
+ end
90
+
91
+ # Invalidates the current cookie
92
+ # @return [Boolean] true if successful
93
+ def logout
94
+ originalConnectUrl = @connecturl
95
+ begin
96
+ @connecturl = @connecturl.gsub(/rest\/api\/.+/,"rest/") # Unfortunately the session information is not in the same tree as all the other rest calls
97
+ con = Connect.new(self)
98
+ ret = con.execute("Delete","auth/latest/session","").code
99
+ store_cookiejar if @autosave
100
+ return true if ret == "204"
101
+ rescue
102
+ raise
103
+ ensure
104
+ @connecturl = originalConnectUrl
105
+ end
106
+ end
107
+
108
+ # Loads a cookiejar from disk
109
+ def load_cookiejar
110
+ storage = PStore.new(File.expand_path(@cookiestore))
111
+ storage.transaction do
112
+ @cookiejar = storage["cookiejar"]
113
+ end
114
+ @cookiejar = {} if @cookiejar.nil? # Fix a not so nice feature of PStore if it doesn't find content in the file
115
+ end
116
+
117
+ # Writes the cookiejar to disk
118
+ def store_cookiejar
119
+ storage = PStore.new(File.expand_path(@cookiestore))
120
+ storage.transaction do
121
+ storage["cookiejar"] = @cookiejar
122
+ end
123
+ end
124
+
125
+
126
+ end
@@ -21,20 +21,12 @@ require "uri"
21
21
  # A Credentials object contains the data required to connect to a JIRA(tm) instance.
22
22
  class Credentials
23
23
 
24
- # username to use
25
- attr_accessor :username
26
- # password for the connection
27
- attr_accessor :password
28
24
  # url to connect to the JIRA(tm) instance
29
25
  attr_reader :connecturl
30
26
 
31
27
 
32
28
  # @param [String] url URL to JIRA(tm) instance
33
- # @param [String] username
34
- # @param [String] password
35
- def initialize(url,username,password)
36
- @username = username
37
- @password = password
29
+ def initialize(url)
38
30
  uri = URI(url)
39
31
  if uri.instance_of?(URI::HTTP) || uri.instance_of?(URI::HTTPS) then
40
32
  @connecturl = url
@@ -54,4 +46,10 @@ class Credentials
54
46
  end
55
47
  end
56
48
 
49
+ # Get the auth header to send to the server
50
+ # @param [Net:::HTTP::Post,Net:::HTTP::Put,Net:::HTTP::Get,Net:::HTTP::Delete] request Request object
51
+ def get_auth_header(request)
52
+
53
+ end
54
+
57
55
  end
@@ -21,11 +21,15 @@ module Jirarest2
21
21
 
22
22
  # 400 -
23
23
  class BadRequestError < StandardError ; end
24
- # 401 Authentification failed
25
- class AuthentificationError < StandardError ; end
26
- # 403 Authentification failed and JIRA(tm) requires a login with captcha to continue
27
- class AuthentificationCaptchaError < StandardError ; end
28
- # 403 Authentification failed
24
+ # 401 Authentication failed
25
+ class AuthenticationError < StandardError ; end
26
+ # 401 Authentication failed with password authentication
27
+ class PasswordAuthenticationError < AuthenticationError ; end
28
+ # 401 Authentication failed with cookie authentication
29
+ class CookieAuthenticationError < AuthenticationError ; end
30
+ # 403 Authentication failed and JIRA(tm) requires a login with captcha to continue
31
+ class AuthenticationCaptchaError < StandardError ; end
32
+ # 403 Forbidden
29
33
  class ForbiddenError < StandardError ; end
30
34
  # 404 - Results in HTML body - not JSON
31
35
  class NotFoundError < StandardError ; end
@@ -233,7 +233,7 @@ class Issue
233
233
  # Set the watchers for this Ticket
234
234
  # @param [Connection] connection
235
235
  # @param [Array] watchers Watchers to be added
236
- # @return [Boolean] True if successfull for all
236
+ # @return [Boolean] True if successful for all
237
237
  def add_watchers(connection,watchers)
238
238
  success = false # Return whether we were successful with the watchers
239
239
  watch = Watcher.new(connection,@issuekey)
@@ -76,6 +76,7 @@ require "json"
76
76
  end # JSON or not?
77
77
 
78
78
  return vars
79
+ STDIN.reopen if config_file == "-" #TODO See if this really does what it is supposed to do
79
80
  end # read.configfile
80
81
 
81
82
 
@@ -0,0 +1,63 @@
1
+ # A Credentials object contains the data required to connect to a JIRA(tm) instance.
2
+
3
+ # Copyright (C) 2012 Cyril Bitterich
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require_relative "credentials"
20
+
21
+ # A Credentials object contains the data required to connect to a JIRA(tm) instance.
22
+ class PasswordCredentials < Credentials
23
+
24
+ # username to use
25
+ attr_accessor :username
26
+ # password for the connection
27
+ attr_accessor :password
28
+
29
+ # @param [String] url URL to JIRA(tm) instance
30
+ # @param [String] username
31
+ # @param [String] password
32
+ def initialize(url,username,password)
33
+ super(url)
34
+ @username = username
35
+ @password = password
36
+ =begin
37
+ uri = URI(url)
38
+ if uri.instance_of?(URI::HTTP) || uri.instance_of?(URI::HTTPS) then
39
+ @connecturl = url
40
+ else
41
+ raise Jirarest2::NotAnURLError
42
+ end
43
+ =end
44
+ end
45
+ =begin
46
+ # Throws an Jirarest2::NotAnURLError if the given String is not an URI.
47
+ # @param [String] url
48
+ def connecturl=(url)
49
+ uri = URI(url)
50
+ if uri.instance_of?(URI::HTTP) || uri.instance_of?(URI::HTTPS) then
51
+ @connecturl = url
52
+ else
53
+ raise Jirarest2::NotAnURLError
54
+ end
55
+ end
56
+ =end
57
+ # Get the auth header to send to the server
58
+ # @param [Net:::HTTP::Post,Net:::HTTP::Put,Net:::HTTP::Get,Net:::HTTP::Delete] request Request object
59
+ def get_auth_header(request)
60
+ request.basic_auth @username, @password
61
+ end
62
+
63
+ end
@@ -72,7 +72,7 @@ public
72
72
 
73
73
  #Get the internal name and direction instead of the one in the UI.
74
74
  # @param [String] uiname the way the linktype is shown in the browser
75
- # @return [Array, nil] Array with the name and the direction ("inward" or "outward") if successfull , nil if not
75
+ # @return [Array, nil] Array with the name and the direction ("inward" or "outward") if successful , nil if not
76
76
  def name(uiname)
77
77
  return uiname if @types.has_key?(uiname) # If the name is already correct just bounce it back
78
78
  @types.each { |name,singletype|
@@ -49,6 +49,11 @@ module Jirarest2Bin
49
49
  text["username"] = "#{scriptopts.username}"
50
50
  end
51
51
  text["#password"] = "Your!PassW0rd"
52
+ if scriptopts.nocookieauth.nil? || scriptopts.nocookieauth then
53
+ text["nocookieauth"] = "false"
54
+ else
55
+ text["nocookieauth"] = "true"
56
+ end
52
57
  begin
53
58
  if scriptopts.writeconf == :forcewrite then
54
59
  MadbitConfig::write_configfile(scriptopts.configfile,text,:force)
@@ -75,6 +80,7 @@ module Jirarest2Bin
75
80
  # @param [String] username The Username to show
76
81
  # @return [String] the password as read from the command line
77
82
  def self.get_password(username)
83
+ STDIN.reopen '/dev/tty'
78
84
  password = ask("Enter your password for user \"#{username}\": ") { |q|
79
85
  q.echo = "*"
80
86
  }
@@ -98,25 +104,31 @@ module Jirarest2Bin
98
104
  puts e
99
105
  filefail = false
100
106
  end
101
- scriptopts.url = scriptopts.url + "/rest/api/2/"
102
-
103
- if scriptopts.pass.nil? && !( scriptopts.username.nil?) then
104
- scriptopts.pass = Jirarest2Bin::get_password(scriptopts.username)
105
- end
106
-
107
+ scriptopts.url = (scriptopts.url + "/rest/api/2/") if !( scriptopts.url =~ /\/rest\/api\/2\/$/)
107
108
  missing = Array.new
108
109
  missing << "URL" if scriptopts.url.nil?
109
110
  missing << "username" if scriptopts.username.nil?
110
111
  if missing != [] then
111
112
  puts "Missing essential parameter(s) #{missing.join(",")}. Exiting..."
112
113
  exit 1
114
+ end
115
+
116
+ if !scriptopts.nocookieauth then
117
+ credentials = CookieCredentials.new(scriptopts.url,true)
118
+ credentials.load_cookiejar
119
+ return credentials
120
+ # TODO What to do if the cookie expired?
113
121
  else
114
- return Credentials.new(scriptopts.url, scriptopts.username, scriptopts.pass)
122
+ if scriptopts.pass.nil? && !( scriptopts.username.nil?) then
123
+ scriptopts.pass = Jirarest2Bin::get_password(scriptopts.username)
124
+ end
125
+ return PasswordCredentials.new(scriptopts.url, scriptopts.username, scriptopts.pass)
115
126
  end
116
127
  end # get_credentials
117
128
 
118
129
 
119
130
  # If there is already a connection known returns that connection. If not or if the parameter is true it tries to create a new Connect object
131
+ # @note Don't call this directly as it will fail if your credentials are wrong.
120
132
  # @param [Openstruct] scriptopts The Openstruct object that contains all the options relevant for the script
121
133
  # @param [Connect] connection An existing connection. Will be nil the first time we use it.
122
134
  # @param [Boolean] reconnect Loose an existing connection and build a new one
@@ -126,7 +138,10 @@ module Jirarest2Bin
126
138
  begin
127
139
  connection = Connect.new(get_credentials(scriptopts))
128
140
  connection.heal_uri! # We want to be sure so we try to heal the connection_url if possible
129
- return connection
141
+ connection
142
+ rescue Jirarest2::CookieAuthenticationError => e
143
+ connection.credentials.login(scriptopts.username,scriptopts.pass)
144
+ retry
130
145
  rescue Jirarest2::CouldNotHealURIError => e
131
146
  puts "REST API not found at #{e.to_s}"
132
147
  exit 3
@@ -135,7 +150,40 @@ module Jirarest2Bin
135
150
  return connection
136
151
  end
137
152
  end # get_connection
138
-
153
+
154
+ # Execute a command to the server
155
+ # This version is safe if the credentials are wrong. Extend the case if more requests should be safeguarded.
156
+ # @param [Array] scriptopts Command line options from the calling script
157
+ # @param [Connection,Nil] connection a connection we er to use
158
+ # @param [Symbol] command to execute
159
+ # @param [Array] *args Arguments for the commands to call
160
+ # @return [Connection] The connection we used
161
+ # @return [Object] The object that was called in the command
162
+ # @example get a Connection object
163
+ # connection = Jirarest2Bin::command(@scriptopts,@connection,:connection)
164
+ def self.command(scriptopts,connection,command,*args)
165
+ begin
166
+ if connection.nil? then
167
+ connection = get_connection(scriptopts,connection)
168
+ end
169
+ case command
170
+ when :issue
171
+ return connection, Issue.new(args[0],args[1],connection)
172
+ when :connection
173
+ return connection
174
+ end
175
+ rescue Jirarest2::PasswordAuthenticationError => e
176
+ scriptopts.pass = Jirarest2Bin.get_password(scriptopts.username)
177
+ retry
178
+ rescue Jirarest2::CookieAuthenticationError => e
179
+ connection.credentials.login(scriptopts.username,scriptopts.pass)
180
+ retry
181
+ rescue Jirarest2::AuthenticationCaptchaError => e
182
+ puts "Wrong Password too many times.\nCaptcha time at #{e.to_s} to reenable your account."
183
+ exit 1
184
+ end
185
+
186
+ end
139
187
 
140
188
  # This method is here because I am to lazy to rewrite the options every time
141
189
  # use it with scriptopts = Jirarest2Bin::defaultoptions(opts,scriptopts)
@@ -161,7 +209,7 @@ module Jirarest2Bin
161
209
  end
162
210
 
163
211
 
164
- opts.on_tail("-u", "--username USERNAME", "Your Jira Username if you don't want to use the one in the master file") do |u|
212
+ opts.on_tail("-u", "--username USERNAME", "Your Jira Username if it is not the one in the master file") do |u|
165
213
  scriptopts.username = u
166
214
  end
167
215
 
@@ -176,6 +224,10 @@ module Jirarest2Bin
176
224
  scriptopts.url = url
177
225
  end
178
226
 
227
+ opts.on_tail("--no-cookie", "Don't try to authenticate via cookies") do |nocookie|
228
+ scriptopts.nocookieauth = true
229
+ end
230
+
179
231
  opts.on_tail("-h", "--help", "Display this screen") do
180
232
  puts opts
181
233
  exit
Binary file
@@ -6,7 +6,7 @@ require "jirarest2/services/comment"
6
6
 
7
7
  class TestComment < MiniTest::Unit::TestCase
8
8
  def setup
9
- cred = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
10
10
  @con = Connect.new(cred)
11
11
  end
12
12
 
@@ -1,16 +1,17 @@
1
1
  require "minitest/autorun"
2
2
  require "jirarest2/connect"
3
- require "jirarest2/credentials"
3
+ require "jirarest2/password_credentials"
4
+ require "jirarest2/cookie_credentials"
4
5
  require "webmock/minitest"
5
6
 
6
7
  class TestConnect < MiniTest::Unit::TestCase
7
8
  def setup
8
- cred = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
10
  @con = Connect.new(cred)
10
11
  end
11
12
 
12
13
  def test_access
13
- stub_request(:any,"http://localhost:2990/jiar/rest/api/2/").with(:headers => {"Content-Type:" => "application/json;charset=UTF-8"})
14
+ stub_request(:any,"http://localhost:2990/jira/rest/api/2/").with(:headers => {"Content-Type:" => "application/json;charset=UTF-8"})
14
15
  end
15
16
 
16
17
  def test_executeGET
@@ -32,7 +33,7 @@ class TestConnect < MiniTest::Unit::TestCase
32
33
 
33
34
  def test_check_uri_false
34
35
  stub_request(:get, "http://test:1234@localhost:2990/rest/api/2/dashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 400, :body => "", :headers => {})
35
- cred = Credentials.new("http://localhost:2990/rest/api/2/","test","1234")
36
+ cred = PasswordCredentials.new("http://localhost:2990/rest/api/2/","test","1234")
36
37
  con1 = Connect.new(cred)
37
38
  assert_equal false,con1.check_uri
38
39
  end
@@ -40,7 +41,7 @@ class TestConnect < MiniTest::Unit::TestCase
40
41
  def test_heal_uri
41
42
  stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/dashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => "", :headers => {})
42
43
 
43
- cred = Credentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
44
+ cred = PasswordCredentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
44
45
  con = Connect.new(cred)
45
46
  assert_equal "http://localhost:2990/jira/rest/api/2/",con.heal_uri
46
47
  assert_equal "http://localhost:2990/jira/rest/api/2/",con.heal_uri("http://localhost:2990/jira/rest/api/2/rest/api/2/")
@@ -59,7 +60,7 @@ class TestConnect < MiniTest::Unit::TestCase
59
60
  stub_request(:get, "http://test:1234@localhost:2990/jira//rest/api//2//dashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 404, :body => '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><status><status-code>404</status-code><message>null for uri: http://localhost:2990/jira//rest/api//2//dashboard</message></status>', :headers => {"X-AUSERNAME" => "test" })
60
61
 
61
62
  ## First an URL we can fix
62
- cred = Credentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
63
+ cred = PasswordCredentials.new("http://localhost:2990/jira//rest/api//2//","test","1234")
63
64
  con = Connect.new(cred)
64
65
  assert_equal false,con.check_uri
65
66
 
@@ -71,7 +72,7 @@ class TestConnect < MiniTest::Unit::TestCase
71
72
  def test_notworking_heal_uri!
72
73
  stub_request(:get, "http://test:1234@localhost:2990/secure/Dashboard.jspadashboard").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 400, :body => "", :headers => {})
73
74
  ## And now one we cant't fix
74
- cred = Credentials.new("http://localhost:2990/secure/Dashboard.jspa","test","1234")
75
+ cred = PasswordCredentials.new("http://localhost:2990/secure/Dashboard.jspa","test","1234")
75
76
  con = Connect.new(cred)
76
77
  assert_equal false,con.check_uri
77
78
  assert_raises(Jirarest2::CouldNotHealURIError){ con.heal_uri! }
@@ -0,0 +1,72 @@
1
+ require "minitest/autorun"
2
+ require "jirarest2/cookie_credentials"
3
+ require "net/http"
4
+ require "webmock/minitest"
5
+ require "deb"
6
+
7
+ class TestCookieCredentials < MiniTest::Unit::TestCase
8
+
9
+ def setup
10
+ @cred = CookieCredentials.new("http://localhost:2990/jira/rest/api/2/")
11
+ @header = ["a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout; Path=/myapp", "JSESSIONID=6C3AE9205FFC6E0DEC3353C2D10745D8; Path=/"]
12
+ end
13
+
14
+
15
+ def test_bake_cookies
16
+ result = {"a.xsrf.token"=> "BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout", "JSESSIONID"=>"6C3AE9205FFC6E0DEC3353C2D10745D8"}
17
+ assert_equal result, @cred.bake_cookies(@header)
18
+ end
19
+
20
+ def test_set_cookies
21
+ test_bake_cookies
22
+ end
23
+
24
+ def test_get_cookies
25
+ result = "a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout; JSESSIONID=6C3AE9205FFC6E0DEC3353C2D10745D8"
26
+ @cred.bake_cookies(@header) # If this fails please see if test_bake_cookies fails as well
27
+ assert_equal result, @cred.get_cookies
28
+ end
29
+
30
+ def test_get_auth_header
31
+ result = "a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout; JSESSIONID=6C3AE9205FFC6E0DEC3353C2D10745D8"
32
+ uri = URI(@cred.connecturl)
33
+ @cred.bake_cookies(@header) # If this fails please see if test_bake_cookies fails as well
34
+ req = Net::HTTP::Get.new(uri.request_uri)
35
+ @cred.get_auth_header(req)
36
+ assert_instance_of Net::HTTP::Get, req # make sure we still got the right requestor class
37
+ assert_equal result,req["Cookie"]
38
+ end
39
+
40
+ def test_login_failed
41
+ stub_request(:post, "http://test:12345@localhost:2990/jira/rest/auth/latest/session").with(:body => "{\"username\":\"test\",\"password\":\"12345\"}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 401, :body => "", :headers => {})
42
+ assert_raises(Jirarest2::PasswordAuthenticationError) {
43
+ @cred.login("test","12345")
44
+ }
45
+ end
46
+
47
+ def test_login_successful
48
+ stub_request(:post, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:body => "{\"username\":\"test\",\"password\":\"1234\"}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8'}).to_return(:status => 200, :body => '{"session":{"name":"JSESSIONID","value":"E8FE2A7CDB3306672665739A8E88D674"}}', :headers => {"Set-Cookie" => ["JSESSIONID=E8FE2A7CDB3306672665739A8E88D674; Path=/","a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|39554775813b531f7dcba4aa28bb13b20e602eb9|lin; Path=/jira"]})
49
+ assert_equal "E8FE2A7CDB3306672665739A8E88D674", @cred.login("test","1234")
50
+ end
51
+
52
+ def test_logout # requires test_login_successful to succeed, so not really good :( )
53
+ stub_request(:post, "http://test:1234@localhost:2990/jira/rest/auth/latest/session").with(:body => "{\"username\":\"test\",\"password\":\"1234\"}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8'}).to_return(:status => 200, :body => '{"session":{"name":"JSESSIONID","value":"E8FE2A7CDB3306672665739A8E88D674"}}', :headers => {"Set-Cookie" => ["JSESSIONID=E8FE2A7CDB3306672665739A8E88D674; Path=/","a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|39554775813b531f7dcba4aa28bb13b20e602eb9|lin; Path=/jira"]})
54
+ stub_request(:delete, "http://localhost:2990/jira/rest/auth/latest/session").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'Cookie'=>'JSESSIONID=E8FE2A7CDB3306672665739A8E88D674; a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|39554775813b531f7dcba4aa28bb13b20e602eb9|lin', 'User-Agent'=>'Ruby'}).to_return(:status => 204, :body => "", :headers => {})
55
+ @cred.login("test","1234")
56
+ assert_equal true,@cred.logout
57
+ end
58
+
59
+ def test_store_cookiejar
60
+ @cred.cookiestore = File.dirname(__FILE__) + "/data/cookiejar"
61
+ @cred.bake_cookies(@header)
62
+ expect = {"a.xsrf.token"=>"BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout", "JSESSIONID"=>"6C3AE9205FFC6E0DEC3353C2D10745D8"}
63
+ assert_equal expect, @cred.store_cookiejar
64
+ end
65
+
66
+ def test_load_cookiejar
67
+ @cred.cookiestore = File.dirname(__FILE__) + "/data/cookiejar"
68
+ @cred.load_cookiejar
69
+ assert_equal "a.xsrf.token=BP8Q-WXN6-SKX3-NB5M|11ca22ad2bf3467bee711e5b912536d1fb046a4a|lout; JSESSIONID=6C3AE9205FFC6E0DEC3353C2D10745D8", @cred.get_cookies
70
+ end
71
+
72
+ end
@@ -1,38 +1,26 @@
1
1
  require "minitest/autorun"
2
- require "jirarest2"
2
+ require "jirarest2/credentials"
3
+ require "jirarest2/exceptions"
3
4
 
4
5
  class TestCredentials < MiniTest::Unit::TestCase
5
6
  def setup
6
- @cred = Credentials.new("https://localhost:2990","username","password")
7
- @credc = Credentials.new("https://localhost:2990","username","password")
7
+ @cred = Credentials.new("https://localhost:2990")
8
8
  end
9
9
 
10
10
  def testInitialize
11
- assert_instance_of(Credentials, Credentials.new("https://localhost:2990","username","password") )
11
+ assert_instance_of(Credentials, Credentials.new("https://localhost:2990"))
12
12
  assert_raises(Jirarest2::NotAnURLError) {
13
- Credentials.new("localhost:2990","username","password")
13
+ Credentials.new("localhost:2990")
14
14
  }
15
15
  assert_equal "https://localhost:2990", @cred.connecturl
16
- assert_equal "username", @cred.username
17
- assert_equal "password", @cred.password
18
16
  end
19
17
 
20
18
  def testSetURL
21
- @credc.connecturl = "http://localhost:80"
22
- assert_equal "http://localhost:80", @credc.connecturl
19
+ @cred.connecturl = "http://localhost:80"
20
+ assert_equal "http://localhost:80", @cred.connecturl
23
21
  assert_raises(Jirarest2::NotAnURLError) {
24
- @credc.connecturl = "localhost:80"
22
+ @cred.connecturl = "localhost:80"
25
23
  }
26
24
  end
27
25
 
28
- def testSetPassword
29
- @credc.password = "1234"
30
- assert_equal "1234", @credc.password
31
- end
32
-
33
- def testSetUsername
34
- @credc.username = "test"
35
- assert_equal "test", @credc.username
36
- end
37
-
38
26
  end
@@ -5,7 +5,7 @@ require "webmock/minitest"
5
5
 
6
6
  class TestIssue < MiniTest::Unit::TestCase
7
7
  def setup
8
- @credentials = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
8
+ @credentials = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
9
  @connect = Connect.new(@credentials)
10
10
  raw_response_file = File.new(File.dirname(__FILE__)+"/data/issuespec.txt")
11
11
  stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issue/createmeta/?expand=projects.issuetypes.fields&issuetypeNames=My%20issue%20type&projectKeys=MFTP").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(raw_response_file)
@@ -8,7 +8,7 @@ require "webmock/minitest"
8
8
 
9
9
  class TestIssueLink < MiniTest::Unit::TestCase
10
10
  def setup
11
- cred = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
11
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
12
12
  @con = Connect.new(cred)
13
13
  stub_request(:get, "http://test:1234@localhost:2990/jira/rest/api/2/issueLinkType").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 200, :body => '{"issueLinkTypes":[{"id":"10000","name":"Blocks","inward":"is blocked by","outward":"blocks","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10000"},{"id":"10001","name":"Cloners","inward":"is cloned by","outward":"clones","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10001"},{"id":"10002","name":"Duplicate","inward":"is duplicated by","outward":"duplicates","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10002"},{"id":"10003","name":"Relates","inward":"relates to","outward":"relates to","self":"http://localhost:2990/jira/rest/api/2/issueLinkType/10003"}]}', :headers => {})
14
14
  @link = IssueLink.new(@con)
@@ -18,7 +18,7 @@ class TestIssueLink < MiniTest::Unit::TestCase
18
18
  def test_link_issue_access
19
19
  # check for right to link.
20
20
  stub_request(:post, "http://test:1234@localhost:2990/jira/rest/api/2/issueLink").with(:body => "{\"type\":{\"name\":\"Blocks\"},\"inwardIssue\":{\"key\":\"MFTP-6\"},\"outwardIssue\":{\"key\":\"SP-2\"}}",:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 401, :body => '{"errorMessages":["No Link Issue Permission for issue \'MFTP-6\'"],"errors":{}}', :headers => {})
21
- assert_raises(Jirarest2::AuthentificationError) {
21
+ assert_raises(Jirarest2::PasswordAuthenticationError) {
22
22
  @link.link_issue("MFTP-6","SP-2","Blocks")
23
23
  }
24
24
  end
@@ -8,7 +8,7 @@ require "webmock/minitest"
8
8
 
9
9
  class TestIssueLinkType < MiniTest::Unit::TestCase
10
10
  def setup
11
- cred = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
11
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
12
12
  @con = Connect.new(cred)
13
13
  end
14
14
 
@@ -1,6 +1,6 @@
1
1
  require "minitest/autorun"
2
2
  require "jirarest2/madbitconfig"
3
- require "pp"
3
+ require "deb"
4
4
 
5
5
  class TestConfig < MiniTest::Unit::TestCase
6
6
 
@@ -0,0 +1,26 @@
1
+ require "minitest/autorun"
2
+ require "jirarest2/password_credentials"
3
+
4
+ class TestPasswordCredentials < MiniTest::Unit::TestCase
5
+ def setup
6
+ @cred = PasswordCredentials.new("https://localhost:2990","username","password")
7
+ end
8
+
9
+ def testInitialize
10
+ assert_instance_of(PasswordCredentials, @cred)
11
+ assert_equal "https://localhost:2990", @cred.connecturl
12
+ assert_equal "username", @cred.username
13
+ assert_equal "password", @cred.password
14
+ end
15
+
16
+ def testSetPassword
17
+ @cred.password = "1234"
18
+ assert_equal "1234", @cred.password
19
+ end
20
+
21
+ def testSetUsername
22
+ @cred.username = "test"
23
+ assert_equal "test", @cred.username
24
+ end
25
+
26
+ end
@@ -6,7 +6,7 @@ require "webmock/minitest"
6
6
 
7
7
  class TestResult < MiniTest::Unit::TestCase
8
8
  def setup
9
- cred = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
9
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
10
10
  @con = Connect.new(cred)
11
11
  end
12
12
 
@@ -7,7 +7,7 @@ require "webmock/minitest"
7
7
 
8
8
  class TestWatcher < MiniTest::Unit::TestCase
9
9
  def setup
10
- cred = Credentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
10
+ cred = PasswordCredentials.new("http://localhost:2990/jira/rest/api/2/","test","1234")
11
11
  @con = Connect.new(cred)
12
12
  end
13
13
 
@@ -27,7 +27,7 @@ class TestWatcher < MiniTest::Unit::TestCase
27
27
  stub_request(:delete, "http://test:1234@localhost:2990/jira/rest/api/2/issue/MFTP-7/watchers?username=cebit").with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 401, :body => '{"errorMessages":["User \'test\' is not allowed to remove watchers from issue \'MFTP-7\'"],"errors":{}}', :headers => {})
28
28
 
29
29
  watchers = Watcher.new(@con,"MFTP-7")
30
- assert_raises(Jirarest2::AuthentificationError) {
30
+ assert_raises(Jirarest2::PasswordAuthenticationError) {
31
31
  watchers.remove_watcher("cebit")
32
32
  }
33
33
  end
@@ -36,7 +36,7 @@ class TestWatcher < MiniTest::Unit::TestCase
36
36
  stub_request(:post, "http://test:1234@localhost:2990/jira/rest/api/2/issue/MFTP-2/watchers").with(:body => "\"cebit\"", :headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json;charset=UTF-8', 'User-Agent'=>'Ruby'}).to_return(:status => 401, :body => '{"errorMessages":["User \'test\' is not allowed to add watchers to issue \'MFTP-2\'"],"errors":{}}', :headers => {})
37
37
 
38
38
  watcherna = Watcher.new(@con, "MFTP-2")
39
- assert_raises(Jirarest2::AuthentificationError) {
39
+ assert_raises(Jirarest2::PasswordAuthenticationError) {
40
40
  watcherna.add_watcher("cebit")
41
41
  }
42
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jirarest2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -50,7 +50,7 @@ cert_chain:
50
50
  -----END CERTIFICATE-----
51
51
 
52
52
  '
53
- date: 2012-08-02 00:00:00.000000000 Z
53
+ date: 2012-08-05 00:00:00.000000000 Z
54
54
  dependencies:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json
@@ -136,7 +136,7 @@ description: ! "jirarest2 is yet another implementation of the JIRA(tm) REST-API
136
136
  . This one for Ruby1.9.1\n\nIt is intended to be called within the shell to create
137
137
  and verify JIRA(tm) issues fast without a browser. There was no particular need
138
138
  for perfomance at the time of writing.\n\nThis implementation is still a for cry
139
- from others like http://rubygems.org/gems/jira-ruby which requires oauth authentification.
139
+ from others like http://rubygems.org/gems/jira-ruby which requires oauth authentication.
140
140
  \n\nThere are scripts to create new issues with watchers and link those to existing
141
141
  issues and to manipulate watchers on existing issues.\n\n *Use it at your own risk.
142
142
  Most of the API features are not implemented.*\n\n *Ruby1.9.1 is needed. Ruby1.8
@@ -144,10 +144,8 @@ description: ! "jirarest2 is yet another implementation of the JIRA(tm) REST-API
144
144
  email:
145
145
  - cebit-jirarest@gunnet.de
146
146
  executables:
147
- - create_issue.rb
148
147
  - jira_comment
149
148
  - jira_create_issue
150
- - jira_create_issue.rb
151
149
  - jira_watcher
152
150
  extensions: []
153
151
  extra_rdoc_files:
@@ -161,18 +159,19 @@ files:
161
159
  - Manifest.txt
162
160
  - README.txt
163
161
  - Rakefile
164
- - bin/create_issue.rb
165
162
  - bin/jira_comment
166
163
  - bin/jira_create_issue
167
- - bin/jira_create_issue.rb
168
164
  - bin/jira_watcher
169
165
  - copyright
166
+ - lib/deb.rb
170
167
  - lib/jirarest2.rb
171
168
  - lib/jirarest2/connect.rb
169
+ - lib/jirarest2/cookie_credentials.rb
172
170
  - lib/jirarest2/credentials.rb
173
171
  - lib/jirarest2/exceptions.rb
174
172
  - lib/jirarest2/issue.rb
175
173
  - lib/jirarest2/madbitconfig.rb
174
+ - lib/jirarest2/password_credentials.rb
176
175
  - lib/jirarest2/result.rb
177
176
  - lib/jirarest2/services.rb
178
177
  - lib/jirarest2/services/comment.rb
@@ -180,6 +179,7 @@ files:
180
179
  - lib/jirarest2/services/issuelinktype.rb
181
180
  - lib/jirarest2/services/watcher.rb
182
181
  - lib/jirarest2bin.rb
182
+ - test/data/cookiejar
183
183
  - test/data/get-comments.txt
184
184
  - test/data/issuespec.txt
185
185
  - test/data/test.config.data
@@ -189,11 +189,13 @@ files:
189
189
  - test/data/ticket.json
190
190
  - test/test_comment.rb
191
191
  - test/test_connect.rb
192
+ - test/test_cookie_credentials.rb
192
193
  - test/test_credentials.rb
193
194
  - test/test_issue.rb
194
195
  - test/test_issuelink.rb
195
196
  - test/test_issuelinktype.rb
196
197
  - test/test_madbitconfig.rb
198
+ - test/test_password_credentials.rb
197
199
  - test/test_result.rb
198
200
  - test/test_watcher.rb
199
201
  - .gemtest
@@ -228,10 +230,12 @@ summary: jirarest2 is yet another implementation of the JIRA(tm) REST-API[https:
228
230
  test_files:
229
231
  - test/test_madbitconfig.rb
230
232
  - test/test_connect.rb
233
+ - test/test_cookie_credentials.rb
231
234
  - test/test_issuelinktype.rb
232
235
  - test/test_comment.rb
233
236
  - test/test_credentials.rb
234
237
  - test/test_issue.rb
238
+ - test/test_password_credentials.rb
235
239
  - test/test_result.rb
236
240
  - test/test_issuelink.rb
237
241
  - test/test_watcher.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Script to create a new issue with jira.
4
- # Copyright (C) 2012 Cyril Bitterich
5
- #
6
- # This program is free software: you can redistribute it and/or modify
7
- # it under the terms of the GNU General Public License as published by
8
- # the Free Software Foundation, either version 3 of the License, or
9
- # (at your option) any later version.
10
- #
11
- # This program is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU General Public License for more details.
15
- #
16
- # You should have received a copy of the GNU General Public License
17
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
- #
19
-
20
- puts "File has been renamed to jira_create_issue"
21
- newfile = File.dirname($0) + "/jira_create_issue"
22
- puts "Please use: #{newfile} #{$*.join(" ")}"
23
-