Skip to content

Commit

Permalink
Allow authenticating via oauth with the private_token
Browse files Browse the repository at this point in the history
The authentication method is detected based on the length of the
authentication token. At the moment GitLab uses
`Devise.friendly_token` for private_tokens which have a length of 20
chars. OAuth tokens are generated with
`Doorkeeper::OAuth::Helpers::UniqueToken.generate` which are 64
characters long.
  • Loading branch information
dsander committed Mar 14, 2015
1 parent 7e1b408 commit 2253fba
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 32 deletions.
8 changes: 5 additions & 3 deletions lib/gitlab/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ module Gitlab
class API < Request
# @private
attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
# @private
alias_method :auth_token=, :private_token=

# Creates a new API.
# @raise [Error:MissingCredentials]
def initialize(options={})
options = Gitlab.options.merge(options)
Configuration::VALID_OPTIONS_KEYS.each do |key|
send("#{key}=", options[key])
(Configuration::VALID_OPTIONS_KEYS + [:auth_token]).each do |key|
send("#{key}=", options[key]) if options[key]
end
set_request_defaults @endpoint, @private_token, @auth_token, @sudo
set_request_defaults(@sudo)
end
end
end
2 changes: 0 additions & 2 deletions lib/gitlab/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ def self.run(cmd, args=[])
when 'info'
endpoint = Gitlab.endpoint ? Gitlab.endpoint : 'not set'
private_token = Gitlab.private_token ? Gitlab.private_token : 'not set'
auth_token = Gitlab.auth_token ? Gitlab.auth_token : 'not set'
puts "Gitlab endpoint is #{endpoint}"
puts "Gitlab private token is #{private_token}"
puts "Gitlab auth token is #{auth_token}"
puts "Ruby Version is #{RUBY_VERSION}"
puts "Gitlab Ruby Gem #{Gitlab::VERSION}"
when '-v', '--version'
Expand Down
7 changes: 4 additions & 3 deletions lib/gitlab/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ module Gitlab
# Defines constants and methods related to configuration.
module Configuration
# An array of valid keys in the options hash when configuring a Gitlab::API.
VALID_OPTIONS_KEYS = [:endpoint, :private_token, :auth_token, :user_agent, :sudo, :httparty].freeze
VALID_OPTIONS_KEYS = [:endpoint, :private_token, :user_agent, :sudo, :httparty].freeze

# The user agent that will be sent to the API endpoint if none is set.
DEFAULT_USER_AGENT = "Gitlab Ruby Gem #{Gitlab::VERSION}".freeze

# @private
attr_accessor(*VALID_OPTIONS_KEYS)
# @private
alias_method :auth_token=, :private_token=

# Sets all configuration options to their default values
# when this module is extended.
Expand All @@ -31,8 +33,7 @@ def options
# Resets all configuration options to the defaults.
def reset
self.endpoint = ENV['GITLAB_API_ENDPOINT']
self.private_token = ENV['GITLAB_API_PRIVATE_TOKEN']
self.auth_token = ENV['GITLAB_API_AUTH_TOKEN']
self.private_token = ENV['GITLAB_API_PRIVATE_TOKEN'] || ENV['GITLAB_API_AUTH_TOKEN']
self.sudo = nil
self.user_agent = DEFAULT_USER_AGENT
end
Expand Down
18 changes: 7 additions & 11 deletions lib/gitlab/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Request
headers 'Accept' => 'application/json'
parser Proc.new { |body, _| parse(body) }

attr_accessor :private_token, :auth_token, :endpoint
attr_accessor :private_token, :endpoint

# Converts the response body to an ObjectifiedHash.
def self.parse(body)
Expand Down Expand Up @@ -77,27 +77,23 @@ def validate(response)

# Sets a base_uri and default_params for requests.
# @raise [Error::MissingCredentials] if endpoint not set.
def set_request_defaults(endpoint, private_token, auth_token, sudo=nil)
raise Error::MissingCredentials.new("Please set an endpoint to API") unless endpoint
@private_token = private_token
@auth_token = auth_token
@endpoint = endpoint

def set_request_defaults(sudo=nil)
raise Error::MissingCredentials.new("Please set an endpoint to API") unless @endpoint
self.class.default_params :sudo => sudo
self.class.default_params.delete(:sudo) if sudo.nil?
end

private

# Sets a PRIVATE-TOKEN or Authorization header for requests.
# @raise [Error::MissingCredentials] if private_token and auth_token are set.
# @raise [Error::MissingCredentials] if private_token and auth_token are not set.
def set_authorization_header(options, path=nil)
unless path == '/session'
raise Error::MissingCredentials.new("Please set a private_token or auth_token for user") unless @private_token || @auth_token
if @private_token
raise Error::MissingCredentials.new("Please provide a private_token or auth_token for user") unless @private_token
if @private_token.length <= 20
options[:headers] = {'PRIVATE-TOKEN' => @private_token}
else
options[:headers] = {'Authorization' => "Bearer #{@auth_token}"}
options[:headers] = {'Authorization' => "Bearer #{@private_token}"}
end
end
end
Expand Down
20 changes: 10 additions & 10 deletions spec/gitlab/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@
describe "#set_request_defaults" do
context "when endpoint is not set" do
it "should raise Error::MissingCredentials" do
@request.endpoint = nil
expect {
@request.set_request_defaults(nil, 1234000, 1234000)
@request.set_request_defaults
}.to raise_error(Gitlab::Error::MissingCredentials, 'Please set an endpoint to API')
end
end

context "when endpoint is set" do
it "should set instance variable 'endpoint'" do
@request.set_request_defaults('http://rabbit-hole.example.org', 1234000, 1234000)
expect(@request.instance_variable_get(:@endpoint)).to eq("http://rabbit-hole.example.org")
before(:each) do
@request.endpoint = 'http://rabbit-hole.example.org'
end

it "should set default_params" do
Gitlab::Request.new.set_request_defaults('http://rabbit-hole.example.org', 1234000, 1234000, 'sudoer')
@request.set_request_defaults('sudoer')
expect(Gitlab::Request.default_params).to eq({:sudo => 'sudoer'})
end
end
Expand All @@ -60,13 +60,13 @@
end

it "should set the correct header when given a private_token" do
@request.private_token = 1234000
expect(@request.send(:set_authorization_header, {})).to eq({"PRIVATE-TOKEN"=>1234000})
@request.private_token = 'ys9BtunN3rDKbaJCYXaN'
expect(@request.send(:set_authorization_header, {})).to eq({"PRIVATE-TOKEN"=>'ys9BtunN3rDKbaJCYXaN'})
end

it "should set the correct header when given a auth_token" do
@request.auth_token = 1234000
expect(@request.send(:set_authorization_header, {})).to eq({"Authorization"=>"Bearer 1234000"})
it "should set the correct header when setting an auth_token via the private_token config option" do
@request.private_token = '3225e2804d31fea13fc41fc83bffef00cfaedc463118646b154acc6f94747603'
expect(@request.send(:set_authorization_header, {})).to eq({"Authorization"=>"Bearer 3225e2804d31fea13fc41fc83bffef00cfaedc463118646b154acc6f94747603"})
end
end

Expand Down
11 changes: 8 additions & 3 deletions spec/gitlab_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
expect(client1.private_token).to eq('001')
expect(client2.private_token).to eq('002')
end

it "should set private_token to the auth_token when provided" do
client = Gitlab.client(endpoint: 'https://api2.example.com', auth_token: '3225e2804d31fea13fc41fc83bffef00cfaedc463118646b154acc6f94747603')
expect(client.private_token).to eq('3225e2804d31fea13fc41fc83bffef00cfaedc463118646b154acc6f94747603')
end
end

describe ".actions" do
Expand All @@ -42,9 +47,9 @@
end

describe ".auth_token=" do
it "should set auth_token" do
Gitlab.auth_token = 'secret'
expect(Gitlab.auth_token).to eq('secret')
it "should set auth_token", focus: true do
Gitlab.auth_token = 'auth_secret'
expect(Gitlab.private_token).to eq('auth_secret')
end
end

Expand Down

0 comments on commit 2253fba

Please sign in to comment.