Permalink
Browse files

Add basic auth, some code cleanup as well.

  • Loading branch information...
1 parent 71da9fe commit 4871839f7f0721b2820b0e8ab76da866f666c7d6 @jstewart committed Nov 1, 2012
View
@@ -5,6 +5,7 @@ pkg/*
*.swp
*.swo
TAGS
+vendor/bundle
*~
\#*#
*.#*
View
@@ -10,8 +10,14 @@ Before doing anything, you must configure your session:
config.password = "yourpass"
config.uri = "http://example.com/foo/bar"
config.api_version = "latest"
+ config.auth_type = :basic
end
+Default auth type is now Basic auth. Cookie auth is still available with the
+following option:
+
+ config.auth_type = :cookie
+
Search for issues:
result = Jiralicious.search("key = HSP-1") # Any jql can be used here
View
@@ -12,8 +12,6 @@ Gem::Specification.new do |s|
s.description = %Q{A Ruby library for interacting with JIRA's REST API}
s.email = "jstewart@fusionary.com"
s.authors = ["Jason Stewart"]
- # Include your dependencies below. Runtime dependencies are required when using your gem,
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
s.add_runtime_dependency 'httparty', '~>0.7.8'
s.add_runtime_dependency 'hashie', '~>1.1'
s.add_runtime_dependency 'json', '~>1.6.3'
View
@@ -11,14 +11,17 @@
require 'jiralicious/search'
require 'jiralicious/search_result'
require 'jiralicious/session'
+require 'jiralicious/basic_session'
+require 'jiralicious/cookie_session'
module Jiralicious
extend Configuration
extend self
def session
- @session ||= Session.new
+ session_type = "#{self.auth_type.to_s.capitalize}Session"
+ @session ||= Jiralicious.const_get(session_type).new
end
def rest_path
@@ -0,0 +1,7 @@
+module Jiralicious
+ class BasicSession < Session
+ def before_request
+ self.class.basic_auth(Jiralicious.username, Jiralicious.password)
+ end
+ end
+end
@@ -2,8 +2,9 @@
module Jiralicious
module Configuration
- VALID_OPTIONS = [:username, :password, :uri, :api_version]
+ VALID_OPTIONS = [:username, :password, :uri, :api_version, :auth_type]
DEFAULT_USERNAME = nil
+ DEFAULT_AUTH_TYPE = :basic
DEFAULT_PASSWORD = nil
DEFAULT_URI = nil
DEFAULT_API_VERSION = "latest"
@@ -30,6 +31,7 @@ def reset
self.password = DEFAULT_PASSWORD
self.uri = DEFAULT_URI
self.api_version = DEFAULT_API_VERSION
+ self.auth_type = DEFAULT_AUTH_TYPE
end
end
end
@@ -0,0 +1,91 @@
+# encoding: utf-8
+
+module Jiralicious
+ class CookieSession < Session
+ attr_accessor :authenticating, :session, :login_info
+
+ def alive?
+ @session && @login_info
+ end
+
+ def before_request
+ self.login if require_login? && !@authenticating
+ end
+
+ def after_request(response)
+ unless @authenticating
+ if captcha_required(response)
+ raise Jiralicious::CaptchaRequired.
+ new("Captacha is required. Try logging into Jira via the web interface")
+ elsif cookie_invalid(response)
+ # Can usually be fixed by logging in again
+ clear_session
+ raise Jiralicious::CookieExpired
+ end
+ end
+ @authenticating = false
+ end
+
+ def login
+ @authenticating = true
+ response = self.request(:post, '/rest/auth/latest/session',
+ :body => { :username => Jiralicious.username,
+ :password => Jiralicious.password}.to_json)
+
+ if response.code == 200
+ response = JSON.parse(response.body)
+ @session = response["session"]
+ @login_info = response["loginInfo"]
+ self.class.cookies({self.session["name"] => self.session["value"]})
+ else
+ clear_session
+ case response.code
+ when 401 then
+ raise Jiralicious::InvalidLogin.new("Invalid login")
+ when 403
+ raise Jiralicious::CaptchaRequired.new("Captacha is required. Try logging into Jira via the web interface")
+ else
+ # Give Net::HTTP reason
+ raise Jiralicious::JiraError.new(response.body)
+ end
+ end
+ end
+
+ def logout
+ response = request(:delete, '/rest/auth/latest/session')
+
+ if response.code == 204
+ clear_session
+ else
+ case response.code
+ when 401 then
+ raise Jiralicious::NotLoggedIn.new("Not logged in")
+ else
+ # Give Net::HTTP reason
+ raise Jiralicious::JiraError.new(response.message)
+ end
+ end
+ end
+
+ private
+
+ def captcha_required(response)
+ response.code == 401 &&
+ # Fakeweb lowercases headers automatically. :(
+ (response.headers["X-Seraph-LoginReason"] == "AUTHENTICATION_DENIED" ||
+ response.headers["x-seraph-loginreason"] == "AUTHENTICATION_DENIED")
+ end
+
+ def cookie_invalid(response)
+ response.code == 401 && response.body =~ /cookie/i
+ end
+
+ def require_login?
+ !(Jiralicious.username.empty? && Jiralicious.password.empty?) && !alive?
+ end
+
+ def clear_session
+ @session = @login_info = nil
+ end
+ end
+end
View
@@ -8,37 +8,41 @@ class Issue < Hashie::Trash
property :jira_self, :from => :self
property :fields
property :transitions
+ property :id
def initialize(decoded_json, default = nil, &blk)
super(decoded_json)
parse!(decoded_json["fields"])
end
def self.find(key, options = {})
- response = Jiralicious.session.perform_request do
- Jiralicious::Session.get("#{Jiralicious.rest_path}/issue/#{key}")
- end
+ response = Jiralicious.session.request(:get, "#{Jiralicious.rest_path}/issue/#{key}")
if response.code == 200
response = JSON.parse(response.body)
+ elsif response.code == 404
+ raise Jiralicious::IssueNotFound.new(response.body)
else
- raise Jiralicious::IssueNotFound
+ raise Jiralicious::JiraError.new(response.body)
end
new(response)
end
def self.get_transitions(transitions_url)
- response = Jiralicious.session.perform_request do
- Jiralicious::Session.get(transitions_url)
+ response = Jiralicious.session.request(:get, transitions_url)
+
+ if response.code == 200
+ response = JSON.parse(response.body)
+ elsif response.code == 404
+ raise Jiralicious::IssueNotFound.new(response.body)
+ else
+ raise Jiralicious::JiraError.new(response.body)
end
- JSON.parse(response.body)
end
def self.transition(transitions_url, data)
- response = Jiralicious.session.perform_request do
- Jiralicious::Session.post(transitions_url, :body => data.to_json)
- end
+ response = Jiralicious.session.request(:post, transitions_url, :body => data.to_json)
case response.code
when 204
@@ -51,6 +55,5 @@ def self.transition(transitions_url, data)
raise Jiralicious::IssueNotFound.new(error['errorMessages'].join('\n'))
end
end
-
end
end
@@ -10,11 +10,14 @@ def parse!(fields)
singleton = class << self; self end
fields.each do |field, details|
- next if details["name"].nil?
- method_value = mashify(details["value"])
- method_name = details["name"].gsub(/(\w+)([A-Z].*)/, '\1_\2').
- gsub(/\W/, "_").
- downcase
+ if details.is_a?(Hash)
+ next if details["name"].nil?
+ method_value = mashify(details["value"])
+ method_name = normalize(details["name"])
+ else
+ method_value = mashify(details)
+ method_name = normalize(field)
+ end
if singleton.method_defined?(method_name)
method_name = "jira_#{method_name}"
@@ -29,6 +32,12 @@ def parse!(fields)
private
+ def normalize(name)
+ name.gsub(/(\w+)([A-Z].*)/, '\1_\2').
+ gsub(/\W/, "_").
+ downcase
+ end
+
def mashify(data)
if data.is_a?(Array)
data.map { |d| mashify(d) }
View
@@ -10,12 +10,11 @@ def search(jql, options = {})
:maxResults => options[:max_results]
}.to_json
- response = Jiralicious.session.perform_request do
- Jiralicious::Session.post(
- "#{Jiralicious.rest_path}/search",
- :body => request_body
- )
- end
+ response = Jiralicious.session.request(
+ :post,
+ "#{Jiralicious.rest_path}/search",
+ :body => request_body
+ )
if response.code == 200
Jiralicious::SearchResult.new(JSON.parse(response.body))
View
@@ -4,97 +4,15 @@
module Jiralicious
class Session
include HTTParty
- attr_accessor :session, :login_info
headers 'Content-Type' => 'application/json'
- def alive?
- @session && @login_info
- end
-
- def login
- response = perform_request(:authenticating => true) do
- self.class.post('/rest/auth/latest/session',
- :body => {
- :username => Jiralicious.username,
- :password => Jiralicious.password}.to_json)
- end
-
- if response.code == 200
- response = JSON.parse(response.body)
- @session = response["session"]
- @login_info = response["loginInfo"]
- self.class.cookies({self.session["name"] => self.session["value"]})
- else
- clear_session
- case response.code
- when 401 then
- raise Jiralicious::InvalidLogin.new("Invalid login")
- when 403
- raise Jiralicious::CaptchaRequired.new("Captacha is required. Try logging into Jira via the web interface")
- else
- # Give Net::HTTP reason
- raise Jiralicious::JiraError.new(response.response.message)
- end
- end
- end
-
- def logout
- response = perform_request do
- self.class.delete('/rest/auth/latest/session')
- end
-
- if response.code == 204
- clear_session
- else
- case response.code
- when 401 then
- raise Jiralicious::NotLoggedIn.new("Not logged in")
- else
- # Give Net::HTTP reason
- raise Jiralicious::JiraError.new(response.response.message)
- end
- end
- end
-
- def perform_request(options = {}, &block)
+ def request(method, *options)
self.class.base_uri Jiralicious.uri
- self.login if require_login? && !options[:authenticating]
+ before_request if respond_to?(:before_request)
+ response = self.class.send(method, *options)
+ after_request(response) if respond_to?(:after_request)
- response = block.call
- unless options[:authenticating]
- if captcha_required(response)
- raise Jiralicious::CaptchaRequired.
- new("Captacha is required. Try logging into Jira via the web interface")
- elsif cookie_invalid(response)
- # Can usually be fixed by logging in again
- clear_session
- self.login
- response = block.call
- raise Jiralicious::CookieExpired if cookie_invalid(response)
- end
- end
response
end
-
- private
-
- def captcha_required(response)
- response.code == 401 &&
- # Fakeweb lowercases headers automatically. :(
- (response.headers["X-Seraph-LoginReason"] == "AUTHENTICATION_DENIED" ||
- response.headers["x-seraph-loginreason"] == "AUTHENTICATION_DENIED")
- end
-
- def cookie_invalid(response)
- response.code == 401 && response.body =~ /cookie/i
- end
-
- def require_login?
- !(Jiralicious.username.empty? && Jiralicious.password.empty?) && !alive?
- end
-
- def clear_session
- @session = @login_info = nil
- end
end
end
Oops, something went wrong.

0 comments on commit 4871839

Please sign in to comment.