omniauth-jira 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +11 -0
- data/Guardfile +11 -0
- data/README.md +19 -0
- data/Rakefile +9 -0
- data/lib/omniauth-jira.rb +3 -0
- data/lib/omniauth-jira/version.rb +5 -0
- data/lib/omniauth/strategies/jira.rb +50 -0
- data/omniauth-jira.gemspec +27 -0
- data/spec/omniauth/strategies/jira_spec.rb +147 -0
- data/spec/spec_helper.rb +16 -0
- metadata +209 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
omniauth-jira
|
2
|
+
=============
|
3
|
+
|
4
|
+
A simple [OmniAuth](https://github.com/intridea/omniauth) strategy for Atlassian JIRA.
|
5
|
+
|
6
|
+
Usage
|
7
|
+
-----
|
8
|
+
|
9
|
+
use OmniAuth::Builder do
|
10
|
+
provider :JIRA,
|
11
|
+
"<consumer_key>",
|
12
|
+
OpenSSL::PKey::RSA.new(IO.read(File.dirname(__FILE__) + "<PRIVATE_KEY_FILE>")),
|
13
|
+
:client_options => { :site => "<http://jira.url>" }
|
14
|
+
end
|
15
|
+
|
16
|
+
Contributing
|
17
|
+
------------
|
18
|
+
|
19
|
+
Do it.
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'omniauth-oauth'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
module OmniAuth
|
6
|
+
module Strategies
|
7
|
+
class JIRA < OmniAuth::Strategies::OAuth
|
8
|
+
|
9
|
+
option :name, "JIRA"
|
10
|
+
option :client_options, {
|
11
|
+
:signature_method => 'RSA-SHA1',
|
12
|
+
:request_token_path => '/plugins/servlet/oauth/request-token',
|
13
|
+
:authorize_path => "/plugins/servlet/oauth/authorize",
|
14
|
+
:access_token_path => '/plugins/servlet/oauth/access-token',
|
15
|
+
:site => nil
|
16
|
+
}
|
17
|
+
|
18
|
+
uid{ raw_info['name'] }
|
19
|
+
|
20
|
+
info do
|
21
|
+
{
|
22
|
+
:name => raw_info['name'],
|
23
|
+
:self => raw_info['self']
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
extra do
|
28
|
+
{
|
29
|
+
'raw_info' => raw_info
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def consumer
|
34
|
+
consumer = ::OAuth::Consumer.new(options.consumer_key, options.consumer_secret, options.client_options)
|
35
|
+
consumer.http.open_timeout = options.open_timeout if options.open_timeout
|
36
|
+
consumer.http.read_timeout = options.read_timeout if options.read_timeout
|
37
|
+
consumer.http.set_debug_output($stderr)
|
38
|
+
consumer
|
39
|
+
end
|
40
|
+
|
41
|
+
def raw_info
|
42
|
+
@raw_info ||= MultiJson.decode(access_token.get('/rest/auth/1/session').body)
|
43
|
+
rescue ::Errno::ETIMEDOUT
|
44
|
+
raise ::Timeout::Error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
OmniAuth.config.add_camelization 'jira', 'JIRA'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/omniauth-jira/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Rich Manalang"]
|
6
|
+
gem.email = ["rmanalang@atlassian.com"]
|
7
|
+
gem.description = %q{A JIRA OAuth 1.0a strategy for OmniAuth.}
|
8
|
+
gem.summary = %q{A JIRA OAuth 1.0a strategy for OmniAuth.}
|
9
|
+
gem.homepage = "https://github.com/manalang/omniauth-jira"
|
10
|
+
|
11
|
+
gem.add_dependency 'multi_json', '~> 1.3'
|
12
|
+
gem.add_runtime_dependency 'omniauth', '~> 1.0'
|
13
|
+
gem.add_runtime_dependency 'omniauth-oauth', '~> 1.0'
|
14
|
+
gem.add_runtime_dependency 'oauth'
|
15
|
+
gem.add_development_dependency 'rspec', '~> 2.7'
|
16
|
+
gem.add_development_dependency 'webmock'
|
17
|
+
gem.add_development_dependency 'simplecov'
|
18
|
+
gem.add_development_dependency 'rack-test'
|
19
|
+
gem.add_development_dependency 'rake'
|
20
|
+
|
21
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
gem.files = `git ls-files`.split("\n")
|
23
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
gem.name = "omniauth-jira"
|
25
|
+
gem.require_paths = ["lib"]
|
26
|
+
gem.version = OmniAuth::JIRA::VERSION
|
27
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "OmniAuth::Strategies::JIRA" do
|
4
|
+
class MyOAuthProvider < OmniAuth::Strategies::OAuth
|
5
|
+
uid{ access_token.token }
|
6
|
+
info{ {'name' => access_token.token} }
|
7
|
+
end
|
8
|
+
|
9
|
+
def app
|
10
|
+
Rack::Builder.new {
|
11
|
+
use OmniAuth::Test::PhonySession
|
12
|
+
use OmniAuth::Builder do
|
13
|
+
provider MyOAuthProvider, 'abc', 'def', :client_options => {:site => 'https://api.example.org'}, :name => 'example.org'
|
14
|
+
provider MyOAuthProvider, 'abc', 'def', :client_options => {:site => 'https://api.example.org'}, :authorize_params => {:abc => 'def'}, :name => 'example.org_with_authorize_params'
|
15
|
+
provider MyOAuthProvider, 'abc', 'def', :client_options => {:site => 'https://api.example.org'}, :request_params => {:scope => 'http://foobar.example.org'}, :name => 'example.org_with_request_params'
|
16
|
+
end
|
17
|
+
run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
|
18
|
+
}.to_app
|
19
|
+
end
|
20
|
+
|
21
|
+
def session
|
22
|
+
last_request.env['rack.session']
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
stub_request(:post, 'https://api.example.org/oauth/request_token').
|
27
|
+
to_return(:body => "oauth_token=yourtoken&oauth_token_secret=yoursecret&oauth_callback_confirmed=true")
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should add a camelization for itself' do
|
31
|
+
OmniAuth::Utils.camelize('oauth').should == 'OAuth'
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '/auth/{name}' do
|
35
|
+
context 'successful' do
|
36
|
+
before do
|
37
|
+
get '/auth/example.org'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should redirect to authorize_url' do
|
41
|
+
last_response.should be_redirect
|
42
|
+
last_response.headers['Location'].should == 'https://api.example.org/oauth/authorize?oauth_token=yourtoken'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should redirect to authorize_url with authorize_params when set' do
|
46
|
+
get '/auth/example.org_with_authorize_params'
|
47
|
+
last_response.should be_redirect
|
48
|
+
[
|
49
|
+
'https://api.example.org/oauth/authorize?abc=def&oauth_token=yourtoken',
|
50
|
+
'https://api.example.org/oauth/authorize?oauth_token=yourtoken&abc=def'
|
51
|
+
].should be_include(last_response.headers['Location'])
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should set appropriate session variables' do
|
55
|
+
session['oauth'].should == {"example.org" => {'callback_confirmed' => true, 'request_token' => 'yourtoken', 'request_secret' => 'yoursecret'}}
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should pass request_params to get_request_token' do
|
59
|
+
get '/auth/example.org_with_request_params'
|
60
|
+
WebMock.should have_requested(:post, 'https://api.example.org/oauth/request_token').
|
61
|
+
with {|req| req.body == "scope=http%3A%2F%2Ffoobar.example.org" }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'unsuccessful' do
|
66
|
+
before do
|
67
|
+
stub_request(:post, 'https://api.example.org/oauth/request_token').
|
68
|
+
to_raise(::Net::HTTPFatalError.new(%Q{502 "Bad Gateway"}, nil))
|
69
|
+
get '/auth/example.org'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should call fail! with :service_unavailable' do
|
73
|
+
last_request.env['omniauth.error'].should be_kind_of(::Net::HTTPFatalError)
|
74
|
+
last_request.env['omniauth.error.type'] = :service_unavailable
|
75
|
+
end
|
76
|
+
|
77
|
+
context "SSL failure" do
|
78
|
+
before do
|
79
|
+
stub_request(:post, 'https://api.example.org/oauth/request_token').
|
80
|
+
to_raise(::OpenSSL::SSL::SSLError.new("SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed"))
|
81
|
+
get '/auth/example.org'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should call fail! with :service_unavailable' do
|
85
|
+
last_request.env['omniauth.error'].should be_kind_of(::OpenSSL::SSL::SSLError)
|
86
|
+
last_request.env['omniauth.error.type'] = :service_unavailable
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '/auth/{name}/callback' do
|
93
|
+
before do
|
94
|
+
stub_request(:post, 'https://api.example.org/oauth/access_token').
|
95
|
+
to_return(:body => "oauth_token=yourtoken&oauth_token_secret=yoursecret")
|
96
|
+
get '/auth/example.org/callback', {:oauth_verifier => 'dudeman'}, {'rack.session' => {'oauth' => {"example.org" => {'callback_confirmed' => true, 'request_token' => 'yourtoken', 'request_secret' => 'yoursecret'}}}}
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should exchange the request token for an access token' do
|
100
|
+
last_request.env['omniauth.auth']['provider'].should == 'example.org'
|
101
|
+
last_request.env['omniauth.auth']['extra']['access_token'].should be_kind_of(OAuth::AccessToken)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should call through to the master app' do
|
105
|
+
last_response.body.should == 'true'
|
106
|
+
end
|
107
|
+
|
108
|
+
context "bad gateway (or any 5xx) for access_token" do
|
109
|
+
before do
|
110
|
+
stub_request(:post, 'https://api.example.org/oauth/access_token').
|
111
|
+
to_raise(::Net::HTTPFatalError.new(%Q{502 "Bad Gateway"}, nil))
|
112
|
+
get '/auth/example.org/callback', {:oauth_verifier => 'dudeman'}, {'rack.session' => {'oauth' => {"example.org" => {'callback_confirmed' => true, 'request_token' => 'yourtoken', 'request_secret' => 'yoursecret'}}}}
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should call fail! with :service_unavailable' do
|
116
|
+
last_request.env['omniauth.error'].should be_kind_of(::Net::HTTPFatalError)
|
117
|
+
last_request.env['omniauth.error.type'] = :service_unavailable
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "SSL failure" do
|
122
|
+
before do
|
123
|
+
stub_request(:post, 'https://api.example.org/oauth/access_token').
|
124
|
+
to_raise(::OpenSSL::SSL::SSLError.new("SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed"))
|
125
|
+
get '/auth/example.org/callback', {:oauth_verifier => 'dudeman'}, {'rack.session' => {'oauth' => {"example.org" => {'callback_confirmed' => true, 'request_token' => 'yourtoken', 'request_secret' => 'yoursecret'}}}}
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should call fail! with :service_unavailable' do
|
129
|
+
last_request.env['omniauth.error'].should be_kind_of(::OpenSSL::SSL::SSLError)
|
130
|
+
last_request.env['omniauth.error.type'] = :service_unavailable
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '/auth/{name}/callback with expired session' do
|
136
|
+
before do
|
137
|
+
stub_request(:post, 'https://api.example.org/oauth/access_token').
|
138
|
+
to_return(:body => "oauth_token=yourtoken&oauth_token_secret=yoursecret")
|
139
|
+
get '/auth/example.org/callback', {:oauth_verifier => 'dudeman'}, {'rack.session' => {}}
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should call fail! with :session_expired' do
|
143
|
+
last_request.env['omniauth.error'].should be_kind_of(::OmniAuth::NoSessionError)
|
144
|
+
last_request.env['omniauth.error.type'] = :session_expired
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.unshift File.expand_path('..', __FILE__)
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start
|
5
|
+
require 'rspec'
|
6
|
+
require 'rack/test'
|
7
|
+
require 'webmock/rspec'
|
8
|
+
require 'omniauth'
|
9
|
+
require 'omniauth-oauth'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.include WebMock::API
|
13
|
+
config.include Rack::Test::Methods
|
14
|
+
config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
|
15
|
+
end
|
16
|
+
|
metadata
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omniauth-jira
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rich Manalang
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: multi_json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: omniauth
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: omniauth-oauth
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: oauth
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '2.7'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.7'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: webmock
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: simplecov
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rack-test
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rake
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: A JIRA OAuth 1.0a strategy for OmniAuth.
|
159
|
+
email:
|
160
|
+
- rmanalang@atlassian.com
|
161
|
+
executables: []
|
162
|
+
extensions: []
|
163
|
+
extra_rdoc_files: []
|
164
|
+
files:
|
165
|
+
- .gitignore
|
166
|
+
- .rspec
|
167
|
+
- Gemfile
|
168
|
+
- Guardfile
|
169
|
+
- README.md
|
170
|
+
- Rakefile
|
171
|
+
- lib/omniauth-jira.rb
|
172
|
+
- lib/omniauth-jira/version.rb
|
173
|
+
- lib/omniauth/strategies/jira.rb
|
174
|
+
- omniauth-jira.gemspec
|
175
|
+
- spec/omniauth/strategies/jira_spec.rb
|
176
|
+
- spec/spec_helper.rb
|
177
|
+
homepage: https://github.com/manalang/omniauth-jira
|
178
|
+
licenses: []
|
179
|
+
post_install_message:
|
180
|
+
rdoc_options: []
|
181
|
+
require_paths:
|
182
|
+
- lib
|
183
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
184
|
+
none: false
|
185
|
+
requirements:
|
186
|
+
- - ! '>='
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
segments:
|
190
|
+
- 0
|
191
|
+
hash: 4141054069828415443
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
segments:
|
199
|
+
- 0
|
200
|
+
hash: 4141054069828415443
|
201
|
+
requirements: []
|
202
|
+
rubyforge_project:
|
203
|
+
rubygems_version: 1.8.21
|
204
|
+
signing_key:
|
205
|
+
specification_version: 3
|
206
|
+
summary: A JIRA OAuth 1.0a strategy for OmniAuth.
|
207
|
+
test_files:
|
208
|
+
- spec/omniauth/strategies/jira_spec.rb
|
209
|
+
- spec/spec_helper.rb
|