improvmx 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6d7859f7b94f30a8fd712321821172498e179e1de7a8a5e893e46a3f131339b1
4
+ data.tar.gz: c468089b24a881419a854ef0cb2ef7597342f77789304f61293d2b1ff1e134dd
5
+ SHA512:
6
+ metadata.gz: 54a26c1b99e2eb1136b07d12026b5ffb73fd5900fd61d7658a634d71e711cc8535741f8c6f4756012b8e114246768a712f13445fef809bd6d1c2726b228a08f1
7
+ data.tar.gz: eed54722a9f29bbaa8d1c7c73b60184d95ec1af7ea13c41e786ff9074d0b30e36f6979eccaf149f8c104cf833147f1fc2944c9eddd1b8af0d0190c21f11e0ace
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Alpha
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ ImprovMX Ruby Gem
2
+ ============
3
+
4
+ Ruby interface to connect to the ImprovMX API.
5
+
6
+ Currently still work in progress, it only contains the aliases endpoints at the moment.
7
+
8
+
9
+ Installation
10
+ ------------
11
+
12
+ ```ruby
13
+ gem install improvmx
14
+ ```
15
+
16
+ Usage
17
+ -----
18
+ This is how you can use this gem
19
+
20
+ ```ruby
21
+ require 'improvmx'
22
+
23
+ # Instantiate the Client with your API key and domain
24
+ client = Improvmx::Client.new 'your-api-key', 'domain.com'
25
+
26
+ # List all the aliases
27
+ aliases = client.list_aliases
28
+
29
+ puts aliases['aliases']
30
+ ```
31
+
32
+ Rails
33
+ -----
34
+
35
+ The library can be initialized with a Rails initializer containing similar:
36
+ ```ruby
37
+ Improvmx.configure do |config|
38
+ config.api_key = 'your-secret-api-key'
39
+ config.domain = 'your-domain'
40
+ end
41
+ ```
42
+
43
+
44
+ For usage examples on each API endpoint, head over to our official documentation
45
+ pages. Or the [Snippets](docs/Snippets.md) file.
46
+
47
+ Testing
48
+ -------
49
+
50
+ There are different test, they require you to setup an ImprovMX account with domain to run.
51
+ By default:
52
+ ```
53
+ bundle exec rake spec
54
+ ```
55
+ will run all the tests.
56
+
57
+ To setup the key information for testing copy `.env.example` to `.env` and fill in the details.
58
+
59
+
60
+ Deployment
61
+ ------
62
+
63
+ This part is for maintaincers only. In order to deploy this gem to rubygem follow those steps:
64
+
65
+ 1. Bump the version in `lib/improvmx/version.rb`
66
+ 1. Build the gem using `gem build improvmx.gemspec`
67
+ 1.
data/improvmx.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'improvmx/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'improvmx'
7
+ spec.version = Improvmx::VERSION
8
+ spec.homepage = 'https://improvmx.com'
9
+ spec.license = 'MIT'
10
+ spec.description = 'Ruby interface for the ImprovMX API'
11
+ spec.summary = 'Ruby interface for the ImprovMX API'
12
+ spec.authors = ['C.S.V. Alpha', 'Matthijs Vos']
13
+ spec.email = 'ict@csvalpha.nl'
14
+
15
+ spec.files = %w[LICENSE README.md improvmx.gemspec] + Dir['lib/**/*.rb']
16
+ spec.require_paths = %w[lib]
17
+
18
+ spec.required_ruby_version = '>= 2.4'
19
+ spec.add_dependency 'rest-client', '>= 2.0.2'
20
+ end
data/lib/improvmx.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rest_client'
2
+ require 'json'
3
+
4
+ require 'improvmx/client'
5
+ require 'improvmx/version'
6
+ require 'improvmx/exceptions/exceptions'
7
+
8
+ # Module for interaction with Improvmx
9
+ module Improvmx
10
+ class << self
11
+ attr_accessor :api_key, :domain
12
+
13
+ def configure
14
+ yield self
15
+ true
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module Improvmx
2
+ # All alias related endpoints
3
+ module Aliases
4
+ def list_aliases(params = {})
5
+ get("/domains/#{domain}/aliases/", params).to_h
6
+ end
7
+
8
+ def get_alias(alias_name)
9
+ get("/domains/#{domain}/aliases/#{alias_name}")
10
+ rescue NotFoundError
11
+ nil
12
+ end
13
+
14
+ def create_alias(alias_name, forward_to)
15
+ response = post("/domains/#{domain}/aliases/", { alias: alias_name, forward: forward(forward_to) })
16
+
17
+ response.ok?
18
+ end
19
+
20
+ def update_alias(alias_name, forward_to)
21
+ response = put("/domains/#{domain}/aliases/#{alias_name}", { forward: forward(forward_to) })
22
+
23
+ response.ok?
24
+ rescue NotFoundError
25
+ false
26
+ end
27
+
28
+ def create_or_update_alias(alias_name, forward_to)
29
+ create_alias(alias_name, forward_to)
30
+ rescue BadRequestError
31
+ update_alias(alias_name, forward_to)
32
+ end
33
+
34
+ def delete_alias(alias_name)
35
+ response = delete("/domains/#{domain}/aliases/#{alias_name}")
36
+
37
+ response.ok?
38
+ rescue NotFoundError
39
+ return true
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,100 @@
1
+ require 'improvmx/aliases'
2
+ require 'improvmx/response'
3
+ require 'improvmx/utils'
4
+ require 'improvmx/exceptions/exceptions'
5
+
6
+ module Improvmx
7
+ class Client
8
+ include Improvmx::Aliases
9
+ include Improvmx::Utils
10
+
11
+ def initialize(api_key = Improvmx.api_key, domain = Improvmx.domain)
12
+ rest_client_params = {
13
+ user: 'api',
14
+ password: api_key,
15
+ user_agent: "improvmx-ruby/#{Improvmx::VERSION}"
16
+ }
17
+
18
+ @http_client = RestClient::Resource.new('https://api.improvmx.com/v3', rest_client_params)
19
+ @domain = domain
20
+ end
21
+
22
+ # Generic Improvmx POST Handler
23
+ #
24
+ # @param [String] resource_path This is the API resource you wish to interact
25
+ # with. Be sure to include your domain, where necessary.
26
+ # @param [Hash] data This should be a standard Hash
27
+ # containing required parameters for the requested resource.
28
+ # @param [Hash] headers Additional headers to pass to the resource.
29
+ # @return [Improvmx::Response] A Improvmx::Response object.
30
+ def post(resource_path, data, headers = {})
31
+ response = @http_client[resource_path].post(data, headers)
32
+ Response.new(response)
33
+ rescue StandardError => e
34
+ raise communication_error e
35
+ end
36
+
37
+ # Generic Improvmx GET Handler
38
+ #
39
+ # @param [String] resource_path This is the API resource you wish to interact
40
+ # with.
41
+ # @param [Hash] params This should be a standard Hash
42
+ # containing required parameters for the requested resource.
43
+ # @param [String] accept Acceptable Content-Type of the response body.
44
+ # @return [Improvmx::Response] A Improvmx::Response object.
45
+ def get(resource_path, params = nil, accept = '*/*')
46
+ response = @http_client[resource_path].get(params: params, accept: accept)
47
+ Response.new(response)
48
+ rescue StandardError => e
49
+ raise communication_error e
50
+ end
51
+
52
+ # Generic Improvmx PUT Handler
53
+ #
54
+ # @param [String] resource_path This is the API resource you wish to interact
55
+ # with.
56
+ # @param [Hash] data This should be a standard Hash
57
+ # containing required parameters for the requested resource.
58
+ # @return [Improvmx::Response] A Improvmx::Response object.
59
+ def put(resource_path, data)
60
+ response = @http_client[resource_path].put(data)
61
+ Response.new(response)
62
+ rescue StandardError => e
63
+ raise communication_error e
64
+ end
65
+
66
+ # Generic Improvmx DELETE Handler
67
+ #
68
+ # @param [String] resource_path This is the API resource you wish to interact
69
+ # with.
70
+ # @return [Improvmx::Response] A Improvmx::Response object.
71
+ def delete(resource_path)
72
+ response = @http_client[resource_path].delete
73
+ Response.new(response)
74
+ rescue StandardError => e
75
+ raise communication_error e
76
+ end
77
+
78
+ attr_reader :domain
79
+
80
+ private
81
+
82
+ # Raises CommunicationError and stores response in it if present
83
+ #
84
+ # @param [StandardException] e upstream exception object
85
+ def communication_error(e) # rubocop:disable Metrics/AbcSize
86
+ if e.respond_to? :response
87
+ code = e.response.code
88
+
89
+ return BadRequestError.new(e.message, e.response) if code == 400
90
+ return AuthenticationError.new(e.message, e.response) if code == 401
91
+ return NotFoundError.new(e.message, e.response) if code == 404
92
+ return RateLimitError.new(e.message, e.response) if code == 429
93
+
94
+ return CommunicationError.new(e.message, e.response)
95
+ end
96
+
97
+ CommunicationError.new(e.message)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,59 @@
1
+ module Improvmx
2
+ class Error < StandardError
3
+ attr_reader :object
4
+
5
+ # Public: initialize a Improvmx:Error object
6
+ #
7
+ # message - a String describing the error
8
+ # object - an object with details about the error
9
+ def initialize(message = nil, object = nil)
10
+ super(message)
11
+ @object = object
12
+ end
13
+ end
14
+
15
+ # Public: Class for managing communications (eg http) response errors
16
+ class CommunicationError < Error
17
+ attr_reader :code
18
+
19
+ # Public: initialization of new error given a message and/or object
20
+ #
21
+ # message - a String detailing the error
22
+ # response - a RestClient::Response object
23
+ #
24
+ def initialize(message = nil, response = nil)
25
+ @response = response
26
+ @code = response.code
27
+
28
+ json = JSON.parse(response.body)
29
+ api_message = json['error'] || json['errors']
30
+
31
+ message ||= ''
32
+ message = "#{message} #{api_message}"
33
+
34
+ super(message, response)
35
+ rescue NoMethodError, JSON::ParserError
36
+ super(message, response)
37
+ end
38
+ end
39
+
40
+ class BadRequestError < CommunicationError
41
+ end
42
+
43
+ class AuthenticationError < CommunicationError
44
+ end
45
+
46
+ class NotFoundError < CommunicationError
47
+ end
48
+
49
+ class RateLimitError < CommunicationError
50
+ attr_reader :wait_seconds
51
+
52
+ def initialize(message = nil, response = nil)
53
+ super(message, response)
54
+
55
+ reset_at = response.headers[:x_ratelimit_reset]
56
+ @wait_seconds = reset_at.to_i - Time.now.to_i
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,26 @@
1
+ module Improvmx
2
+ # Ruby representation of ImprovMX response
3
+ class Response
4
+ attr_accessor :body, :code
5
+
6
+ def initialize(response)
7
+ @body = response.body
8
+ @code = response.code
9
+ end
10
+
11
+ # Return response as Ruby Hash
12
+ #
13
+ # @return [Hash] A standard Ruby Hash containing the HTTP result.
14
+ def to_h
15
+ JSON.parse(@body)
16
+ rescue StandardError => e
17
+ raise ParseError.new(e), e
18
+ end
19
+
20
+ attr_reader :headers
21
+
22
+ def ok?
23
+ @code == 200
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ require 'improvmx/aliases'
2
+ require 'improvmx/response'
3
+ require 'improvmx/exceptions/exceptions'
4
+
5
+ module Improvmx
6
+ # Utils to help processing data
7
+ module Utils
8
+ # Parse the forward to parameter into a comma separated string
9
+ def forward(forward_to)
10
+ return forward_to.join(',') if forward_to.is_a? Array
11
+
12
+ forward_to
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Improvmx
2
+ VERSION = '0.1.0'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: improvmx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - C.S.V. Alpha
8
+ - Matthijs Vos
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2021-03-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 2.0.2
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 2.0.2
28
+ description: Ruby interface for the ImprovMX API
29
+ email: ict@csvalpha.nl
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.md
36
+ - improvmx.gemspec
37
+ - lib/improvmx.rb
38
+ - lib/improvmx/aliases.rb
39
+ - lib/improvmx/client.rb
40
+ - lib/improvmx/exceptions/exceptions.rb
41
+ - lib/improvmx/response.rb
42
+ - lib/improvmx/utils.rb
43
+ - lib/improvmx/version.rb
44
+ homepage: https://improvmx.com
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '2.4'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.0.8
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Ruby interface for the ImprovMX API
67
+ test_files: []