Skip to content

Commit

Permalink
Merge pull request #24 from IBM/1.0.0.rc
Browse files Browse the repository at this point in the history
1.0.0
  • Loading branch information
mamoonraja authored Oct 3, 2019
2 parents a142f35 + c7f35bd commit b8cb695
Show file tree
Hide file tree
Showing 25 changed files with 989 additions and 695 deletions.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ require "ibm_cloud_sdk_core"
```

## Authentication Types
There are several flavors of authentication supported in this package. To specify the intended authentication pattern to use, the user can pass in the parameter `authentication_type`. This parameter is optional, but it may become required in a future major release. The options for this parameter are `basic`, `iam`, and `icp4d`.
There are several flavors of authentication supported in this package. To specify the intended authentication pattern to use, the user can pass in the parameter `authentication_type`. This parameter is optional, but it may become required in a future major release. The options for this parameter are `basic`, `iam`, `bearer_token` and `cp4d`.

### basic
### basic
This indicates Basic Auth is to be used. Users will pass in a `username` and `password` and the SDK will generate a Basic Auth header to send with requests to the service.

### iam
This indicates that IAM token authentication is to be used. Users can pass in an `iam_apikey` or an `iam_access_token`. If an API key is used, the SDK will manage the token for the user. In either case, the SDK will generate a Bearer Auth header to send with requests to the service.
## bearer token
This indicates that bearer token authentication is to be used. Users can pass in an `bearer_token`, and SDK will generate a Bearer Auth header to send with requests to the service.

### icp4d
This indicates that the service is an instance of ICP4D, which has its own version of token authentication. Users can pass in a `username` and `password`, or an `icp4d_access_token`. If a username and password is given, the SDK will manage the token for the user.
A `icp4d_url` is **required** for this type. In order to use an SDK-managed token with ICP4D authentication, this option **must** be passed in.
### iam
This indicates that IAM token authentication is to be used. Users can pass in an `apikey`. The SDK will manage the token for the user and it will generate a Bearer Auth header to send with requests to the service.

### cp4d
This indicates that the service is an instance of ICP4D, which has its own version of token authentication. Users can pass in a `username` and `password`. If a username and password is given, the SDK will manage the token for the user.
A `cp4d_url` is **required** for this type. In order to use an SDK-managed token with ICP4D authentication, this option **must** be passed in.

## Issues

Expand Down
4 changes: 2 additions & 2 deletions ibm_cloud_sdk_core.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency "http", "~> 4.1.0"
spec.add_runtime_dependency "jwt", "~> 2.2.1"

spec.add_development_dependency "bundler", "~> 1.16"
spec.add_development_dependency "bundler", "~> 1.6"
spec.add_development_dependency "codecov", "~> 0.1"
spec.add_development_dependency "dotenv", "~> 2.4"
spec.add_development_dependency "httplog", "~> 1.0"
spec.add_development_dependency "minitest", "~> 5.11"
spec.add_development_dependency "minitest-hooks", "~> 1.5"
spec.add_development_dependency "minitest-reporters", "~> 1.3"
spec.add_development_dependency "minitest-retry", "~> 0.1"
spec.add_development_dependency "rake", "~> 12.3"
spec.add_development_dependency "rake", "~> 13.0"
spec.add_development_dependency "rubocop", "0.62"
spec.add_development_dependency "simplecov", "~> 0.16"
spec.add_development_dependency "webmock", "~> 3.4"
Expand Down
2 changes: 1 addition & 1 deletion lib/ibm_cloud_sdk_core/api_exception.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def initialize(code: nil, error: nil, info: nil, transaction_id: nil, global_tra
@error = response.reason
unless response.body.empty?
body_hash = JSON.parse(response.body.to_s)
error_message = body_hash["errors"] && body_hash["errors"][0] ? body_hash["errors"][0].message : nil
error_message = body_hash["errors"] && body_hash["errors"][0] ? body_hash["errors"][0]["message"] : nil
@code = body_hash["code"] || body_hash["error_code"] || body_hash["status"]
@error = error_message || body_hash["error"] || body_hash["message"] || body_hash["errorMessage"]
%w[code error_code status errors error message].each { |k| body_hash.delete(k) }
Expand Down
22 changes: 22 additions & 0 deletions lib/ibm_cloud_sdk_core/authenticators/authenticator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require("json")

module IBMCloudSdkCore
# Authenticator
class Authenticator
AUTH_TYPE_BASIC = "basic"
AUTH_TYPE_BEARER_TOKEN = "bearerToken"
AUTH_TYPE_CP4D = "cp4d"
AUTH_TYPE_IAM = "iam"
AUTH_TYPE_NO_AUTH = "noAuth"

def authenticate
# Adds the Authorization header, if possible
end

def validate
# Checks if all the inputs needed are present
end
end
end
36 changes: 36 additions & 0 deletions lib/ibm_cloud_sdk_core/authenticators/basic_authenticator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require("json")
require_relative("./authenticator.rb")
require_relative("../utils.rb")

module IBMCloudSdkCore
# Basic Authenticator
class BasicAuthenticator < Authenticator
attr_accessor :username, :password, :authentication_type
def initialize(vars)
defaults = {
username: nil,
password: nil
}
vars = defaults.merge(vars)
@username = vars[:username]
@password = vars[:password]
@authentication_type = AUTH_TYPE_BASIC
validate
end

# Adds the Authorization header, if possible
def authenticate(headers)
base64_authentication = Base64.strict_encode64("#{@username}:#{@password}")
headers["Authorization"] = "Basic #{base64_authentication}"
end

# Checks if all the inputs needed are present
def validate
raise ArgumentError.new("The username and password shouldn\'t be None.") if @username.nil? || @password.nil?
raise ArgumentError.new('The username shouldn\'t start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your username') if check_bad_first_or_last_char(@username)
raise ArgumentError.new('The password shouldn\'t start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your password') if check_bad_first_or_last_char(@password)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

require("json")
require_relative("./authenticator.rb")
require_relative("../utils.rb")

module IBMCloudSdkCore
# Basic Authenticator
class BearerTokenAuthenticator < Authenticator
attr_accessor :authentication_type
def initialize(vars)
defaults = {
bearer_token: nil
}
vars = defaults.merge(vars)
@bearer_token = vars[:bearer_token]
@authentication_type = AUTH_TYPE_BEARER_TOKEN
validate
end

# Adds the Authorization header, if possible
def authenticate(headers)
headers["Authorization"] = "Bearer #{@bearer_token}"
end

# Checks if all the inputs needed are present
def validate
raise ArgumentError.new("The bearer token shouldn\'t be None.") if @bearer_token.nil?
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require("json")
require_relative("./authenticator.rb")
require_relative("./basic_authenticator.rb")
require_relative("./bearer_token_authenticator.rb")
require_relative("./cp4d_authenticator.rb")
require_relative("./iam_authenticator.rb")
require_relative("./no_auth_authenticator.rb")
require_relative("../utils.rb")

module IBMCloudSdkCore
# Authenticator
class ConfigBasedAuthenticatorFactory < Authenticator
# Checks the credentials file and VCAP_SERVICES environment variable
# :param service_name: The service name
# :return: the authenticator
def get_authenticator(service_name:)
config = get_service_properties(service_name)
return construct_authenticator(config) unless config.nil? || config.empty?
end

def construct_authenticator(config)
if config[:auth_type].nil?
auth_type = "iam"
else
auth_type = config[:auth_type]
end
config.delete(:url) unless config[:url].nil?
config[:url] = config[:auth_url] unless config[:auth_url].nil?
return BasicAuthenticator.new(config) if auth_type.casecmp(AUTH_TYPE_BASIC).zero?
return BearerTokenAuthenticator.new(config) if auth_type.casecmp(AUTH_TYPE_BEARER_TOKEN).zero?
return CloudPakForDataAuthenticator.new(config) if auth_type.casecmp(AUTH_TYPE_CP4D).zero?
return IamAuthenticator.new(config) if auth_type.casecmp(AUTH_TYPE_IAM).zero?
return NoAuthAuthenticator.new if auth_type.casecmp(AUTH_TYPE_NO_AUTH).zero?
end
end
end
49 changes: 49 additions & 0 deletions lib/ibm_cloud_sdk_core/authenticators/cp4d_authenticator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

require("json")
require_relative("./authenticator.rb")
require_relative("../token_managers/cp4d_token_manager.rb")
require_relative("../utils.rb")

module IBMCloudSdkCore
# Basic Authenticator
class CloudPakForDataAuthenticator < Authenticator
attr_accessor :authentication_type, :disable_ssl_verification
def initialize(vars)
defaults = {
username: nil,
password: nil,
url: nil,
disable_ssl_verification: false
}
vars = defaults.merge(vars)
@username = vars[:username]
@password = vars[:password]
@url = vars[:url]
@disable_ssl_verification = vars[:disable_ssl_verification]
@authentication_type = AUTH_TYPE_CP4D

validate
@token_manager = CP4DTokenManager.new(
url: @url,
username: @username,
password: @password,
disable_ssl_verification: @disable_ssl_verification
)
end

# Adds the Authorization header, if possible
def authenticate(headers)
headers["Authorization"] = "Bearer #{@token_manager.access_token}"
end

# Checks if all the inputs needed are present
def validate
raise ArgumentError.new("The username or password shouldn\'t be None.") if @username.nil? || @password.nil?
raise ArgumentError.new("The url shouldn\'t be None.") if @url.nil?
raise ArgumentError.new('The username shouldn\'t start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your username') if check_bad_first_or_last_char(@username)
raise ArgumentError.new('The password shouldn\'t start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your password') if check_bad_first_or_last_char(@password)
raise ArgumentError.new('The url shouldn\'t start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your url') if check_bad_first_or_last_char(@url)
end
end
end
50 changes: 50 additions & 0 deletions lib/ibm_cloud_sdk_core/authenticators/iam_authenticator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

require("json")
require_relative("./authenticator.rb")
require_relative("../token_managers/iam_token_manager.rb")
require_relative("../utils.rb")

module IBMCloudSdkCore
# Basic Authenticator
class IamAuthenticator < Authenticator
attr_accessor :authentication_type, :disable_ssl_verification, :client_id, :client_secret
def initialize(vars)
defaults = {
url: nil,
client_id: nil,
client_secret: nil,
disable_ssl_verification: nil
}
vars = defaults.merge(vars)
@apikey = vars[:apikey]
@url = vars[:url]
@client_id = vars[:client_id]
@client_secret = vars[:client_secret]
@disable_ssl_verification = vars[:disable_ssl_verification]
@authentication_type = AUTH_TYPE_IAM

validate
@token_manager = IAMTokenManager.new(
apikey: @apikey,
url: @url,
client_id: @client_id,
client_secret: @client_secret,
disable_ssl_verification: @disable_ssl_verification
)
end

def authenticate(headers)
headers["Authorization"] = "Bearer #{@token_manager.access_token}"
end

def validate
# Adds the Authorization header, if possible
raise ArgumentError.new("The apikey shouldn\'t be None.") if @apikey.nil?
raise ArgumentError.new('The apikey shouldn\'t start or end with curly brackets or quotes. Be sure to remove any {} and \" characters surrounding your apikey') if check_bad_first_or_last_char(@apikey)

# Both the client id and secret should be provided or neither should be provided.
raise ArgumentError.new("Only one of 'client_id' or 'client_secret' were specified, but both parameters should be specified together.") if (@client_id.nil? && !@client_secret.nil?) || (!@client_id.nil? && @client_secret.nil?)
end
end
end
21 changes: 21 additions & 0 deletions lib/ibm_cloud_sdk_core/authenticators/no_auth_authenticator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

require("json")
require_relative("./authenticator.rb")

module IBMCloudSdkCore
# Authenticator
class NoAuthAuthenticator < Authenticator
def initialize
@authentication_type = AUTH_TYPE_NO_AUTH
end

def authenticate
nil
end

def validate
nil
end
end
end
Loading

0 comments on commit b8cb695

Please sign in to comment.