class MxHero::API::Client

A client to interact with mxhero engine API

Public Class Methods

new(config = {}) click to toggle source

@param [Hash] config the options of configuration @option config [String] :api_url The URL to consume the API @option config [String] :username The username for access the API @option config [String] :password The password for the user that access the API @option config [Boolean] :verbose (false) If true puts information about http operations @option config [String] :as_user Send to the API to indentify the end user (app user email)

# File lib/mxhero-api.rb, line 34
def initialize(config = {})
        @service_url = config[:api_url]
        @username = config[:username]
        @password = config[:password]
        @verbose = config[:verbose] || false
        @as_user = config[:as_user]
end

Public Instance Methods

account_properties(domain, account) click to toggle source

@param [String] domain @param [String] account Ex.: test or mxhero (the user name) @return [MxHero::API::Response] reponse

the key :msg contains a Hash with the key, value of any property.
Example:

    { 'email': 'test@mxhero.com', 'name': 'John', 'lastname': 'Doe', ... }
# File lib/mxhero-api.rb, line 340
def account_properties(domain, account)
        url = account_properties_url(domain, account)
        response = call(:get, url)
        if response.status == 200
                props = {}
                json_parse(response.content).each { |property| props[property[:name]] = property[:value] }
                return Response.new(response.code, props)
        end
        parse_response(response)
end
accounts_by_domain(domain, refinement = {}) click to toggle source

Retrive all the account from one domain

@params [String] domain @params [String] filter_account the account to filter in the list. This can be a part of an account. @param [Hash] refinement @option refinement [Fixnum] :limit of elements per page @option refinement [Fixnum] :offset number of page (start in 1) @option refinement [String] :account filter accounts that start with this value @option refinement [Boolean] :without_group filter accounts without group

@return [Hash] with the following elements:

* :elements [Array<Hash>] the list of accounts as a Hash, when any element contains:
  * :account [String] example: alex
  * :domain [String] example: mxhero.com
  * :createdDate [Fixnum] example: 1375909565000 (epoch format)
  * :updatedDate [Fixnum]
  * :group [String]
  * :aliases [Array<Hash>] the list of aliases of one account
    * :name [String]
    * :domain [String]
    * :dataSource [String]
  * :dataSource [String]
* :totalElements [Fixnum]
* :totalPages [Fixnum]
* :actualPage [Fixnum]

@raise an exception when the status code isn't 200

# File lib/mxhero-api.rb, line 244
def accounts_by_domain(domain, refinement = {}) #filter_account = nil, pagination = {})
        params = refinement.dup
        filter_account = params.delete(:account)
        filter_account = CGI::escape(filter_account) if filter_account
        without_group = params.delete(:without_group) || false
        limit, offset = params.values_at(:limit, :offset)

        if without_group
                url = accounts_without_group_url(domain, filter_account)
        else
                url = paginate accounts_by_domain_url(domain, filter_account), { limit: limit, offset: offset }
        end
        response = call(:get, url)
        json_parse(response.content)
end
accounts_without_group_url(domain, filter_account) click to toggle source
# File lib/mxhero-api.rb, line 260
def accounts_without_group_url(domain, filter_account)
        domain_by_id_url(domain) + "/groups/accounts/available?account=#{filter_account}"
end
add_feature(domain_name, feature_component) click to toggle source

Create a new domain base on domain_obj hash

@param domain_obj The domain to be created. For example:

Hash

with detailed domain

* :domain [String]
* :server [String]
* :inbound [Boolean]
* :outbound [Boolean]
* :features [Array<Hash>]
* :cos [Hash]
* :source [String] (gapps|on_premise|ms_agent|office365)
* :aliases [Array<String>]
* :ldap [Hash]

@return [Boolean] true if was successfully created

# File lib/mxhero-api.rb, line 161
def add_feature(domain_name, feature_component)
        feature = {
                feature: feature_component,
                maxRulesAmount: 1
        }
        response = call(:post, features_url(domain_name), feature.to_json, throw_exception: false)
        response.status == 200
end
associate_user_domain(user, domain) click to toggle source

Associate domains with an existing user @param [String] user @param [String] domains

# File lib/mxhero-api.rb, line 479
def associate_user_domain(user, domain)
        domain_obj = { domain: domain }
        response = call(:post, user_domains_url(user), domain_obj.to_json, throw_exception: false)
        response.status == 200
end
create_domain(domain_obj = {}) click to toggle source

Create a new domain base on domain_obj hash

@param domain_obj The domain to be created. For example:

Hash

with detailed domain

* :domain [String]
* :server [String]
* :inbound [Boolean]
* :outbound [Boolean]
* :features [Array<Hash>]
* :cos [Hash]
* :source [String] (gapps|on_premise|ms_agent|office365)
* :aliases [Array<String>]
* :ldap [Hash]

@return [Boolean] true if was successfully created

# File lib/mxhero-api.rb, line 135
def create_domain(domain_obj = {})
        response = call(:post, domains_url, domain_obj.to_json, throw_exception: false)
        response.status == 201
end
create_rule_for_domain(domain, msg) click to toggle source

@param domain [String] @param [Hash] msg @option msg [String] :domain @option msg [Boolean] :twoWays @option msg [Boolean] :enabled @option msg [String] :name @option msg [Integer] :created in epoch format @option msg [Hash] :fromDirection @option msg [Hash] :toDirection @option msg [Array<Hash>] :properties @option msg [String] :component

@return [MxHero::API::Response]

# File lib/mxhero-api.rb, line 285
def create_rule_for_domain(domain, msg)
        url = rules_for_domain_url(domain)
        response = call(:post, url, msg.to_json, throw_exception: false)
        parse_response(response)
end
create_user(user_info, *domains) click to toggle source

Create a new user @param [Hash] user_info @option user_info [String] :name @option user_info [String] :lastName @option user_info [String] :notifyEmail @option user_info [String] :userName @option user_info [String] :locale @option user_info [String] :password

@param [Array<String>] domains

# File lib/mxhero-api.rb, line 462
def create_user(user_info, *domains)
        user = {
                name: "", lastName: "", notifyEmail: "",
                userName: "", locale: "en_US", password: "1234",
                authorities: ["ROLE_DOMAIN_ADMIN"],
                created: DateTime.now.strftime('%Q'),
                domains: domains.map { |domain| { domain: domain } }
        }
        user.merge!(user_info)
        response = call(:post, users_url, user.to_json, throw_exception: false)
        response.status == 201
end
delete_rule(domain, id) click to toggle source

@return [Boolean] true when operation it's ok

# File lib/mxhero-api.rb, line 325
def delete_rule(domain, id)
        url = domain_rule_url(domain, id)
        response = call(:delete, url)
        return true if response.status == 200
        return false
end
directories(domain) click to toggle source

Expose directories api

@return MxHero::API::Directories

# File lib/mxhero-api.rb, line 45
def directories(domain)
        @directories ||= Directories.new(domain, api_url: @service_url,
                                                                                                                                         username: @username, password: @password,
                                                                                                                                         verbose: @verbose, as_user: @as_user)
end
domain(name) click to toggle source

Retrive the domain information

@param name The domain name or id. For example: 'mydomain.com' @return [Domain] or nil if not found

@raise an exception when the status code is not 200 (ok) or 404 (not found)

# File lib/mxhero-api.rb, line 177
def domain(name)
        domain_info = fetch domain_by_id_url(name), on_error: "An error ocurred when try to fetch the domain #{name}."
        return nil unless domain_info
        Domain.new domain_info
end
domain_rule(domain, id) click to toggle source

Find a rule by domain and ID

@param domain [String] @param id [Integer] the rule id

@return [Hash, nil] the Rule information or nil if not exist

@raise an exception when the status code isn't 200

# File lib/mxhero-api.rb, line 59
def domain_rule(domain, id)
        url = domain_rule_url(domain, id)
        response = call(:get, url)
        raise 'an error ocurred when try to communicate with the API' if response.status != 200
        json_parse(response.content)
end
domains(params = {}) click to toggle source

Retrive all the domains

TODO: Improve the response. We really need manage pagination here?

@return [Hash] with the list of domains

* :elements [Array<Hash>] the list of domains as a Hash, when any element contains:
  * :domain [String]
  * :server [String]
  * :creationDate [Fixnum]
  * :updateDate [Fixnum]
  * :aliases
  * :ldap
* :totalElements
* :totalPages
* :actualPage

@raise an exception when the status code isn't 200

# File lib/mxhero-api.rb, line 99
def domains(params = {})
        url = domains_url
        limit, offset = params.values_at(:limit, :offset)
        url = paginate(domains_url, { limit: limit, offset: offset }) if limit && offset
        response = call(:get, url)
        raise 'an error ocurred when try to communicate with the API' if response.status != 200
        response_as_a_hash = json_parse(response.content)
        response_as_a_hash
end
fetch_user(user) click to toggle source

Fetch the user @return [MxHero::API::Response | nil]

# File lib/mxhero-api.rb, line 442
def fetch_user(user)
        response = call(:get, user_url(user))
        if response.status == 200
                return parse_response(response)
        end
        nil
end
ldap_info(domain) click to toggle source

Fetch the LDAP information of the domain

@return [Hash] with

* :domain
* :directoryType
* :addres
* :port
* :sslFlag [Boolean]
* :user
* :password
* :filter
* :base
* :nextUpdate
* :lastUpdate
* :error
* :overrideFlag
* :dnAuthenticate
* :properties [Array]
# File lib/mxhero-api.rb, line 208
def ldap_info(domain)
        fetch domain_by_id_url(domain) + '/adldap',
                on_error: "An error was ocurred when try to fecht the ldap information of #{domain}"
end
move_to_trial(domain) click to toggle source

Move COS to trial @return true | false

# File lib/mxhero-api.rb, line 112
def move_to_trial(domain)
        url = domain_by_id_url(domain) + '/cos/trial'
        response = call(:put, url)
        response.status == 200
end
regex_tester(test_msg) click to toggle source

test_msg example: {

        "matching":{
            "matcher": [
                {
                "default":false,
                "type":"regex",
                "regex":"(.*)@(.*)",
                "toValue":"${2}/${1}/${0}"
                }
            ],
            "placeholder":"email"
        },
        "value":"smith@example.org",
        "key":"email"
}

Response HTTP: 200 OK {“result”:“example.org/smith/smith@example.org”}

On error, response: HTTP Status 500 {

  "status": 500,
  "code": 500,
  "developerMessage": "Dangling meta character '*' near index 0\n*.(.*)@(.*)\n^",
  "moreInfoUrl": "mailto:support@mxhero.com"
}
# File lib/mxhero-api.rb, line 552
def regex_tester(test_msg)
        response = call(:put, service_url + '/regex/check/pattern', test_msg.to_json, throw_exception: false)
        parse_response(response)
end
reset_password(user_name) click to toggle source
# File lib/mxhero-api.rb, line 518
def reset_password(user_name)
        response = call(:get, user_url_reset_password(user_name), throw_exception: false)
        response.status == 200
end
rule_status(domain, rule_id, enabled = true) click to toggle source

In case of error, the message is completed with the cause of error

# File lib/mxhero-api.rb, line 76
def rule_status(domain, rule_id, enabled = true)
        url = domain_rule_url(domain, rule_id)+"/status?enabled=#{enabled}"
        response = call(:put, url)
        parse_response(response)
end
rules_for_domain(domain, component = nil) click to toggle source

Retrieve all the rules for one domain

@param [String] domain @param [String] component Filter the list of rules by this component [optional]

@return [MxHero::API::Response] reponse

the key :msg contains an array of rules for the domain.
# File lib/mxhero-api.rb, line 317
def rules_for_domain(domain, component = nil)
        url = rules_for_domain_url(domain)
        url << "?component=#{component}" if component
        response = call(:get, url)
        parse_response(response, on_empty: [])
end
save_system_property(key, value) click to toggle source

Update or create a system property

# File lib/mxhero-api.rb, line 404
def save_system_property(key, value)
        property = { key: key, value: value }.to_json
        response = if system_properties(key).nil?
                call(:post, system_properties_url, property)
        else
                call(:put, system_properties_url(key), property)
        end

        parse_response(response).success?
end
set_new_password(user_name, new_password) click to toggle source
# File lib/mxhero-api.rb, line 513
def set_new_password(user_name, new_password)
        response = call(:put, user_url_set_password(user_name, new_password), throw_exception: false)
        response.status == 200
end
system_properties(key = nil) click to toggle source

@return [Hash|String|nil] can return a hash with the key and value of any

system property. If use a parameter (key) return the string of this value.
In the two cases return nil when not found values
# File lib/mxhero-api.rb, line 387
def system_properties(key = nil)
        response = call(:get, system_properties_url(key))
        if response.status == 200
                parsed = json_parse(response.content)
                if parsed.is_a? Array
                        props = {}
                        parsed.each { |property| props[property[:key]] = property[:value] }
                        return props
                else
                        return parsed[:value]
                end
        end

        nil
end
unassociate_user_domain(user, domain) click to toggle source

Unassociate specific domain from an user admin @param [String] user @param [String] domain

# File lib/mxhero-api.rb, line 489
def unassociate_user_domain(user, domain)
        response = call(:delete, user_with_domain_url(user,domain), throw_exception: false)
        response.status == 200
end
update_account_properties(domain, account, properties) click to toggle source

@param [String] domain @param [String] account @param [Hash] properties The properties of the account. Ex.: { 'email': 'test@mxhero.com', 'name': 'John', 'lastname': 'Doe', … }

@return [MxHero::API::Response]. On success not return msg.

# File lib/mxhero-api.rb, line 356
def update_account_properties(domain, account, properties)
        url = account_properties_url(domain, account)
        response = call(:put, url, account_properties_to_json(properties))
        parse_response(response)
end
update_accounts(domain, accounts, scope = :properties) click to toggle source

@param [String] domain @param [Array<Hash>] accounts. An array of hash with :account and :properties. The :properties

contains a Hash with the equivalent of name and value.

@param [String] scope :groups, :properties or :both (default: properties)

# File lib/mxhero-api.rb, line 368
def update_accounts(domain, accounts, scope = :properties)
        scope_param = scope == :both ? 'groups,properties' : scope.to_s
        #url = "/domains/#{domain}/accounts/upload?scope=#{scope_param}"
        url = accounts_by_domain_url(domain) + "/upload?scope=#{scope_param}"

        message = []
        accounts.each do |account|
                properties = remap_properties(account[:properties])
                message << { account: account[:account], properties: properties, group: account[:group], domain: domain }
                #message << { account: account[:account], properties: properties, group: account[:group] }
        end
        response = call(:put, url, message.to_json) # accounts to json
        parse_response(response)
end
update_domain(domain, domain_obj = {}) click to toggle source
# File lib/mxhero-api.rb, line 140
def update_domain(domain, domain_obj = {})
        response = call(:put, domain_by_id_url(domain), domain_obj.to_json, throw_exception: false)
        response.status == 200
end
update_rule(rule) click to toggle source

Update a rule @return [MxHero::API::Response] When the rule is update correctly then return MxHero::API::Response object without msg (msg nil)

In case of error, the message is completed with the cause of error
# File lib/mxhero-api.rb, line 69
def update_rule(rule)
        url = domain_rule_url(rule[:domain], rule[:id])
        response = call(:put, url, rule.to_json)
        parse_response(response)
end
update_user(user, user_name) click to toggle source

Update user @param [Hash] user retrieve to update

@param user_name [String]

# File lib/mxhero-api.rb, line 500
def update_user(user, user_name)
        response = call(:put, user_url(user_name), user.to_json, throw_exception: false)
        parse_response(response)
end
user_domains(user) click to toggle source

Obtain the list of domains to one user @return [Array<String>|nil] when the user exist but don't have domains the list is empty.

If the user isn't exist then return nil
# File lib/mxhero-api.rb, line 430
def user_domains(user)
        domains = nil
        response = call(:get, user_domains_url(user))
        if response.status == 200
                content = json_parse(response.content)
                domains = content.map { |info| info[:domain] }
        end
        domains
end
users_for_domain(domain) click to toggle source

Obtain the list of users admin in a specific domain @return [Array<UserVO>|nil] when there is no users for that domain.

If the domain doesn't exist then return nil
# File lib/mxhero-api.rb, line 418
def users_for_domain(domain)
        users = nil
        response = call(:get, users_for_domain_url(domain), throw_exception: false)
        if response.status == 200
                users = json_parse(response.content)
        end
        users
end
valid_user_credentials?(user, password) click to toggle source

Validate if the an user and password match

# File lib/mxhero-api.rb, line 507
def valid_user_credentials?(user, password)
        validate_user_credential_url = user_url(user) + "/password/check"
        response = call(:post, validate_user_credential_url, password, { content_type: 'text/plain' })
        response.status == 204
end
verbose=(verbose) click to toggle source
# File lib/mxhero-api.rb, line 268
def verbose=(verbose)
        @verbose = verbose
end
verbose?() click to toggle source
# File lib/mxhero-api.rb, line 264
def verbose?
        @verbose
end

Private Instance Methods

account_properties_to_json(properties) click to toggle source
# File lib/mxhero-api.rb, line 636
def account_properties_to_json(properties)
        out = []
        properties.each do |key, value|
                out << { name: key, value: value }
        end
        out.to_json
end
account_properties_url(domain, account) click to toggle source
# File lib/mxhero-api.rb, line 665
def account_properties_url(domain, account)
        accounts_by_domain_url(domain) + "/#{account}/properties"
end
accounts_by_domain_url(domain, filter_account = nil) click to toggle source
# File lib/mxhero-api.rb, line 652
def accounts_by_domain_url(domain, filter_account = nil)
        filter = filter_account ? "?account=#{filter_account}" : ''
        domain_by_id_url(domain) + '/accounts' + filter
end
domain_rule_url(domain, id) click to toggle source
# File lib/mxhero-api.rb, line 657
def domain_rule_url(domain, id)
        rules_for_domain_url(domain) + "/#{id}"
end
features_url(domain) click to toggle source
# File lib/mxhero-api.rb, line 661
def features_url(domain)
        domain_by_id_url(domain) + "/features"
end
fetch(url, msg) click to toggle source

Fetch an element from an URL. That element maybe not found @return a Hash when the element exist. Or return nil when not found.

@raise RuntimeError when an error ocurrs.

# File lib/mxhero-api.rb, line 595
def fetch(url, msg)
        response = call(:get, url)
        return json_parse(response.content) if response.ok?
        return nil if response.code == 404

        error = msg[:on_error] + " HTTP code: #{response.code}"
        if response.content.include?('message')
                hash = json_parse(response.content)
                error << " Response message: #{hash[:message]}"
        end

        raise error
end
paginate(url, pagination) click to toggle source

Complete the URL with the pagination info (:limit and :offset) @param [String] original URL. Ex.: www.example.com/api/accounts @param [Hash] pagination @option pagination [Fixnum] :limit of elements per page @option pagination [Fixnum] :offset number of page (start in 1)

@return [String] the URL with the pagination parameters.

Ex.: url: http://www.example.com/api/accounts
     pagination: { limit: 4, offset: 2 }
     return > http://www.example.com/api/accounts?limit=4&offset=2
# File lib/mxhero-api.rb, line 624
def paginate(url, pagination)
        paginated = url.dup
        connector = url.include?('?') ? '&' : '?'
        [ :limit, :offset ].map do |elem|
                if pagination.key? elem
                        paginated << "#{connector}#{elem.to_s}=#{pagination[elem]}"
                        connector = '&'
                end
        end
        paginated
end
parse_response(response, opts = { on_empty: nil }) click to toggle source

@return [MxHero::API::Response] a response object

# File lib/mxhero-api.rb, line 675
def parse_response(response, opts = { on_empty: nil })
        json = response.content
        hash = json.nil? || json.empty? ? opts[:on_empty] : json_parse(json)
        Response.new(response.code, hash)
end
remap_properties(properties) click to toggle source
# File lib/mxhero-api.rb, line 609
def remap_properties(properties)
        return nil if properties.nil?
        properties.keys.map { |name| { name: name, value: properties[name] } }
end
rules_for_domain_url(domain) click to toggle source
# File lib/mxhero-api.rb, line 644
def rules_for_domain_url(domain)
        service_url + "/domains/#{domain}/rules"
end
rules_url() click to toggle source
# File lib/mxhero-api.rb, line 648
def rules_url
        service_url + '/rules'
end
system_properties_url(key = nil) click to toggle source
# File lib/mxhero-api.rb, line 669
def system_properties_url(key = nil)
        fixed_key = key.nil? ? nil : "#{key}/"
        service_url + "/system/properties/#{fixed_key}"
end
user_domains_url(user) click to toggle source
# File lib/mxhero-api.rb, line 569
def user_domains_url(user)
        user_url(user) + "/domains"
end
user_url(user) click to toggle source
# File lib/mxhero-api.rb, line 565
def user_url(user)
        users_url + "/#{user}"
end
user_url_reset_password(user) click to toggle source
# File lib/mxhero-api.rb, line 586
def user_url_reset_password(user)
        pass_esc = CGI::escape(user)
        users_url + "/resetPassword?email=#{pass_esc}"
end
user_url_set_password(user,new_password) click to toggle source
# File lib/mxhero-api.rb, line 581
def user_url_set_password(user,new_password)
        pass_esc = CGI::escape(new_password)
        users_url + "/#{user}/setPassword?newPassword=#{pass_esc}"
end
user_with_domain_url(user,domain) click to toggle source
# File lib/mxhero-api.rb, line 577
def user_with_domain_url(user,domain)
        user_url(user) + "/domains/#{domain}/"
end
users_for_domain_url(domain) click to toggle source
# File lib/mxhero-api.rb, line 573
def users_for_domain_url(domain)
        users_url + "/domain/#{domain}/"
end
users_url() click to toggle source

# File lib/mxhero-api.rb, line 561
def users_url
        service_url + "/users"
end