Commit 65175efc authored by Jose Ernesto Suarez's avatar Jose Ernesto Suarez

Se mueve todo el modulo Wedoops

parent 0e4138c5
example_id | status | run_time |
----------------------------- | ------ | --------------- |
./spec/zoholib_spec.rb[1:1] | passed | 0.00183 seconds |
./spec/zoholib_spec.rb[1:2] | passed | 0.00144 seconds |
./spec/zoholib_spec.rb[1:3:1] | passed | 0.00112 seconds |
./spec/zoholib_spec.rb[1:3:2] | passed | 0.0012 seconds |
./spec/zoholib_spec.rb[1:3:3] | passed | 0.00009 seconds |
./spec/zoholib_spec.rb[1:3:4] | passed | 0.0002 seconds |
./spec/zoholib_spec.rb[1:3:5] | passed | 0.00022 seconds |
./spec/zoholib_spec.rb[1:1] | passed | 0.00261 seconds |
./spec/zoholib_spec.rb[1:2] | passed | 0.00141 seconds |
./spec/zoholib_spec.rb[1:3:1] | passed | 0.00125 seconds |
./spec/zoholib_spec.rb[1:3:2] | passed | 0.00011 seconds |
./spec/zoholib_spec.rb[1:3:3] | passed | 0.00008 seconds |
./spec/zoholib_spec.rb[1:3:4] | passed | 0.00016 seconds |
./spec/zoholib_spec.rb[1:3:5] | passed | 0.00017 seconds |
......@@ -14,20 +14,22 @@ require 'zoholib/zoho_client'
##
# This library is used for access Zoho
module Zoholib
class << self
attr_accessor :configuration
end
def self.configuration
@configuration ||= Configuration.new
end
def self.reset
@configuration = Configuration.new
end
def self.configure
yield(configuration)
module Wedoops
module Zoholib
class << self
attr_accessor :configuration
end
def self.configuration
@configuration ||= Configuration.new
end
def self.reset
@configuration = Configuration.new
end
def self.configure
yield(configuration)
end
end
end
......@@ -4,93 +4,94 @@ require 'json'
require 'logger'
require 'date'
module Wedoops
module Zoholib
class AdamoClient
module Zoholib
class AdamoClient
def initialize(options={})
@logger = Logger.new(STDOUT)
@http = HTTP
.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "Af8cbSpgkAReYqBs66DHJUkf2MJW3d9JDFVJhWe4U5haD")
end
def initialize(options={})
@logger = Logger.new(STDOUT)
@http = HTTP
.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "Af8cbSpgkAReYqBs66DHJUkf2MJW3d9JDFVJhWe4U5haD")
end
def cobertura_project
count=2
url = "https://coverage-dump.adamo.es/v1/cobertura-project/#{count}?limit=500"
return HTTP.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "Af8cbSpgkAReYqBs66DHJUkf2MJW3d9JDFVJhWe4U5haD").get(url)
end
def cobertura_project
count=2
url = "https://coverage-dump.adamo.es/v1/cobertura-project/#{count}?limit=500"
return HTTP.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "Af8cbSpgkAReYqBs66DHJUkf2MJW3d9JDFVJhWe4U5haD").get(url)
end
def cobertura
page=1
limit=50000
#date=Date.parse("06-04-2020").strftime("%Y%m%d")
date=Date.today.prev_day.strftime("%Y%m%d")
resultado_final=Array.new
r=Array.new
loop do
print "#{page} "
url= "https://coverage-dump.adamo.es/v1/cobertura/#{page}?limit=#{limit}&date=#{date}"
#.use(logging: {logger: @logger})
resultado= HTTP.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "zYkWN38SYH6hr2Ixq75xvDENl6hrYOvxx0FxLvPD7BUe6").get(url)
r= JSON.parse(resultado, symbolize_names: true)
resultado_final.concat(r)
page+=1
print "(#{r.size}/#{resultado_final.size}),"
break if r.size < limit || page >2
end
puts resultado_final.size
return resultado_final
end
def cobertura
page=1
limit=50000
#date=Date.parse("06-04-2020").strftime("%Y%m%d")
date=Date.today.prev_day.strftime("%Y%m%d")
resultado_final=Array.new
r=Array.new
loop do
print "#{page} "
url= "https://coverage-dump.adamo.es/v1/cobertura/#{page}?limit=#{limit}&date=#{date}"
#.use(logging: {logger: @logger})
resultado= HTTP.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "zYkWN38SYH6hr2Ixq75xvDENl6hrYOvxx0FxLvPD7BUe6").get(url)
r= JSON.parse(resultado, symbolize_names: true)
resultado_final.concat(r)
page+=1
print "(#{r.size}/#{resultado_final.size}),"
break if r.size < limit || page >2
end
puts resultado_final.size
return resultado_final
end
def projects
page=1
limit=50000
#date=Date.today.prev_day.strftime("%Y%m%d")
date=Date.parse("01-01-2011").strftime("%Y%m%d")
resultado_final=Array.new
r=Array.new
loop do
print "#{page} "
url= "https://coverage-dump.adamo.es/v1/cobertura-project/#{page}?limit=#{limit}&date=#{date}"
#.use(logging: {logger: @logger})
resultado= HTTP.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "zYkWN38SYH6hr2Ixq75xvDENl6hrYOvxx0FxLvPD7BUe6").get(url)
r= JSON.parse(resultado, symbolize_names: true)
resultado_final.concat(r)
page+=1
print "(#{r.size}/#{resultado_final.size}),"
break if r.size < limit || page >2
end
puts resultado_final.size
return resultado_final
end
def projects
page=1
limit=50000
#date=Date.today.prev_day.strftime("%Y%m%d")
date=Date.parse("01-01-2011").strftime("%Y%m%d")
resultado_final=Array.new
r=Array.new
loop do
print "#{page} "
url= "https://coverage-dump.adamo.es/v1/cobertura-project/#{page}?limit=#{limit}&date=#{date}"
#.use(logging: {logger: @logger})
resultado= HTTP.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache",
"accept" => "application/json",
"postman-token" => "8b126eb1-0de6-4a10-d78d-1fb417fb23b0",
"x-apikey" => "zYkWN38SYH6hr2Ixq75xvDENl6hrYOvxx0FxLvPD7BUe6").get(url)
r= JSON.parse(resultado, symbolize_names: true)
resultado_final.concat(r)
page+=1
print "(#{r.size}/#{resultado_final.size}),"
break if r.size < limit || page >2
end
puts resultado_final.size
return resultado_final
end
private
private
def get_params(url,payload)
@http.get(url, :params => payload)
end
def get_params(url,payload)
@http.get(url, :params => payload)
end
def get(url)
@http.get(url)
end
end
def get(url)
@http.get(url)
end
end
end
end
\ No newline at end of file
......@@ -3,122 +3,123 @@
#En algun momento tenemos que abrir un navegador
require 'launchy'
require 'socket'
module Wedoops
module Zoholib
class AuthorizationRequest < ZohoRequest
module Zoholib
class AuthorizationRequest < ZohoRequest
# Sin en algun momento se quiere evitar el encode de URL
# he aqui un truco
# En esta ocasion lo gastamos porque los scopes vienen separados por una coma que hace que falle
query_string_normalizer proc { |query|
query.map do |key, value|
[value].flatten.map {|v| "#{key}=#{v}"}.join('&')
end.join('&')
}
# Sin en algun momento se quiere evitar el encode de URL
# he aqui un truco
# En esta ocasion lo gastamos porque los scopes vienen separados por una coma que hace que falle
query_string_normalizer proc { |query|
query.map do |key, value|
[value].flatten.map {|v| "#{key}=#{v}"}.join('&')
end.join('&')
}
def initialize(options={})
#build_url(options)
@logger = ::Logger.new(STDOUT)
@options = Hash.new
options.merge!({response_type: 'code',access_type: 'offline',redirect_uri: 'http://localhost:8000/auth/callback'})
@grant_token = options[:grant_token]
#@options.merge!(grant_token: options[:grant_token] )
options.delete(:grant_token)
#Al iniciar este objeto estas opciones solo tienen sentido en query
@options.merge!(query: options)
@logged_in = false
end
def initialize(options={})
#build_url(options)
@logger = ::Logger.new(STDOUT)
@options = Hash.new
options.merge!({response_type: 'code',access_type: 'offline',redirect_uri: 'http://localhost:8000/auth/callback'})
@grant_token = options[:grant_token]
#@options.merge!(grant_token: options[:grant_token] )
options.delete(:grant_token)
#Al iniciar este objeto estas opciones solo tienen sentido en query
@options.merge!(query: options)
@logged_in = false
end
def authorize(options={})
unless @options[:refresh_token].nil?
@logger.warn "Refresh token already exists! Ignoring call"
return @options
end
#El prompt consent obliga a mostrar la pantalla de consent
# de esta manera se consigue que devuelva siempre el
# refresh token que es valido para siempre
if options.has_key?(:force_prompt)
#Si esta opcion la establecemos a true entonces se forzara el consent
@options[:query].merge!(prompt:"consent") if options[:force_prompt]
end
#pp @options
get_grant_token if @grant_token.nil?
tokens = get_grant_request
#pp tokens
raise "Unknown error! I cannot find the refresh_token! try to force prompt" if tokens[:refresh_token].nil?
@options.merge!(tokens)
# Decido devolver tokens unicamente, dejo aqui los comentarios antiguos
def authorize(options={})
unless @options[:refresh_token].nil?
@logger.warn "Refresh token already exists! Ignoring call"
return @options
end
#El prompt consent obliga a mostrar la pantalla de consent
# de esta manera se consigue que devuelva siempre el
# refresh token que es valido para siempre
if options.has_key?(:force_prompt)
#Si esta opcion la establecemos a true entonces se forzara el consent
@options[:query].merge!(prompt:"consent") if options[:force_prompt]
# #Ya no necesitamos estas opciones dentro de query, las sacamos fuera
# # Para devolverselas a nuestro padre
# @options.merge!(@options[:query])
# @options.delete(:query)
# # El code solo tiene un uso y caducal al minuto, asi que
# # Lo eliminamos tambien
# @options.delete(:code)
@options.delete(:follow_redirects)
return tokens
end
#pp @options
get_grant_token if @grant_token.nil?
tokens = get_grant_request
#pp tokens
raise "Unknown error! I cannot find the refresh_token! try to force prompt" if tokens[:refresh_token].nil?
@options.merge!(tokens)
# Decido devolver tokens unicamente, dejo aqui los comentarios antiguos
# #Ya no necesitamos estas opciones dentro de query, las sacamos fuera
# # Para devolverselas a nuestro padre
# @options.merge!(@options[:query])
# @options.delete(:query)
# # El code solo tiene un uso y caducal al minuto, asi que
# # Lo eliminamos tambien
# @options.delete(:code)
@options.delete(:follow_redirects)
return tokens
end
def read_socket(port=8000)
@logger.info "Reading socket response"
server = TCPServer.new port
while session = server.accept
request = session.gets
match = /code=\d{4}\.\w{32}\.\w{32}/.match(request)
if match
code = match.to_s.split("=").last
end
session.print "HTTP/1.1 200\r\n" # 1
session.print "Content-Type: text/html\r\n" # 2
session.print "\r\n" # 3
session.print "Thank you! The time is #{Time.now}" #4
def read_socket(port=8000)
@logger.info "Reading socket response"
server = TCPServer.new port
while session = server.accept
request = session.gets
match = /code=\d{4}\.\w{32}\.\w{32}/.match(request)
if match
code = match.to_s.split("=").last
end
session.print "HTTP/1.1 200\r\n" # 1
session.print "Content-Type: text/html\r\n" # 2
session.print "\r\n" # 3
session.print "Thank you! The time is #{Time.now}" #4
session.close
break
end
server.close
return code
end
session.close
break
def get_grant_token
# Ejecuta lo descrito en el paso 2 del ZOHO OAUTH https://www.zoho.com/crm/developer/docs/api/auth-request.html
# Para recibir el codigo que nos permitira generar los tokens
# Atencion, este metodo abre un navegador para autorizar y un socket en el puerto 8000 para recibir el codigo tras
# la aceptacion de permisos
@options.merge!(follow_redirects: false)
response=self.class.get('/auth', @options)
# puts "RESPONSE CODE:#{response.code}"
if response.code >= 300 && response.code < 400
redirect_url = response.headers['location']
Launchy.open(redirect_url)
grant_token=read_socket
@logger.info "GRANT TOKEN: #{grant_token}"
@grant_token = grant_token
return true
end
raise "Unable to get the grant token!"
end
server.close
return code
end
def get_grant_token
# Ejecuta lo descrito en el paso 2 del ZOHO OAUTH https://www.zoho.com/crm/developer/docs/api/auth-request.html
# Para recibir el codigo que nos permitira generar los tokens
# Atencion, este metodo abre un navegador para autorizar y un socket en el puerto 8000 para recibir el codigo tras
# la aceptacion de permisos
@options.merge!(follow_redirects: false)
response=self.class.get('/auth', @options)
# puts "RESPONSE CODE:#{response.code}"
if response.code >= 300 && response.code < 400
redirect_url = response.headers['location']
Launchy.open(redirect_url)
grant_token=read_socket
@logger.info "GRANT TOKEN: #{grant_token}"
@grant_token = grant_token
return true
def get_grant_request
# Prepara la llamada descrita en el paso 3 del ZOHO OAUTH https://www.zoho.com/crm/developer/docs/api/access-refresh.html
# Para recibir access_token y refresh_token
raise "Unable to get a grant request without grant token!" if @grant_token.nil?
options_grant_request = @options.dup
options_grant_request.delete(:grant_token)
options_grant_request.delete(:follow_redirects)
options_grant_request[:query].delete(:response_type)
options_grant_request[:query].delete(:scope)
options_grant_request[:query].delete(:access_type)
options_grant_request[:query].merge!(code: @grant_token)
grant_request=Zoholib::GrantRequest.new(options_grant_request)
result=grant_request.token
# pp result
raise "Error #{result[:error]}" unless result[:error].nil?
return result
end
raise "Unable to get the grant token!"
end
def get_grant_request
# Prepara la llamada descrita en el paso 3 del ZOHO OAUTH https://www.zoho.com/crm/developer/docs/api/access-refresh.html
# Para recibir access_token y refresh_token
raise "Unable to get a grant request without grant token!" if @grant_token.nil?
options_grant_request = @options.dup
options_grant_request.delete(:grant_token)
options_grant_request.delete(:follow_redirects)
options_grant_request[:query].delete(:response_type)
options_grant_request[:query].delete(:scope)
options_grant_request[:query].delete(:access_type)
options_grant_request[:query].merge!(code: @grant_token)
grant_request=Zoholib::GrantRequest.new(options_grant_request)
result=grant_request.token
# pp result
raise "Error #{result[:error]}" unless result[:error].nil?
return result
end
end
end
\ No newline at end of file
......@@ -5,53 +5,54 @@ require 'logger'
require 'date'
require 'savon'
module Zoholib
class B12Client
module Wedoops
module Zoholib
class B12Client
def initialize(options={})
@logger = Logger.new(STDOUT)
initialize_client
@client.call(:lead)
end
def initialize(options={})
@logger = Logger.new(STDOUT)
initialize_client
@client.call(:lead)
end
def send_lead(lead)
@logger.info("Sending lead: #{lead[:idvar]} tlf:#{lead[:Telefono]}")
#pp lead
#puts ":.................:"
begin
response = @client.call(:lead) do
message(lead)
def send_lead(lead)
@logger.info("Sending lead: #{lead[:idvar]} tlf:#{lead[:Telefono]}")
#pp lead
#puts ":.................:"
begin
response = @client.call(:lead) do
message(lead)
end
rescue Exception => e
@logger.error("Error sending the lead: #{e.message}")
return nil
end
rescue Exception => e
@logger.error("Error sending the lead: #{e.message}")
return nil
end
begin
b12_id = response.body[:lead_response][:return]
unless b12_id.match(/^\d*$/)
raise "Error de B12, envio #{lead[:idvar]} tlf:#{lead[:Telefono]} duplicado (#{b12_id})" if b12_id == "-1"
raise "Error interno de B12, error #{b12_id} recibido"
begin
b12_id = response.body[:lead_response][:return]
unless b12_id.match(/^\d*$/)
raise "Error de B12, envio #{lead[:idvar]} tlf:#{lead[:Telefono]} duplicado (#{b12_id})" if b12_id == "-1"
raise "Error interno de B12, error #{b12_id} recibido"
end
rescue Exception => e
@logger.error("Error getting the LEAD ID: #{e.message}")
return nil
end
rescue Exception => e
@logger.error("Error getting the LEAD ID: #{e.message}")
return nil
return b12_id
end
return b12_id
end
private
private
def initialize_client
@client = Savon.client do
wsdl 'http://panel.digitalion.com/wss/cobalt.lead.php?wsdl'
pretty_print_xml true
#convert_request_keys_to :camelcase
log false
log_level :info
def initialize_client
@client = Savon.client do
wsdl 'http://panel.digitalion.com/wss/cobalt.lead.php?wsdl'
pretty_print_xml true
#convert_request_keys_to :camelcase
log false
log_level :info
end
end
end
end
end
end
\ No newline at end of file
# frozen_string_literal: true
module Wedoops
module Zoholib
##
# This class permits the configuration of the Valenciaport Access.
# Is neccesary the WDSL URLs for the login and transport endpoint
# as well the array with the different credentials wich will be used
class Configuration
attr_accessor :client_id, :client_secret, :scope, :refresh_token
module Zoholib
##
# This class permits the configuration of the Valenciaport Access.
# Is neccesary the WDSL URLs for the login and transport endpoint
# as well the array with the different credentials wich will be used
class Configuration
attr_accessor :client_id, :client_secret, :scope, :refresh_token
def initialize
@client_id = nil
@client_secret = nil
@scope = nil
@refresh_token = nil
end
def initialize
@client_id = nil
@client_secret = nil
@scope = nil
@refresh_token = nil
end
end
end
end
end
\ No newline at end of file
#require './lib/zoho_request'
module Zoholib
class GrantRequest < ZohoRequest
module Wedoops
module Zoholib
class GrantRequest < ZohoRequest
#base_uri "https://accounts.zoho.com/oauth/v2/token"
#headers: {"Authorization" => "Token token=\"111\""}
def initialize(options={})
@logger = ::Logger.new(STDOUT)
@logged_in = false
@options = options
end
#base_uri "https://accounts.zoho.com/oauth/v2/token"
#headers: {"Authorization" => "Token token=\"111\""}
def initialize(options={})
@logger = ::Logger.new(STDOUT)
@logged_in = false
@options = options
end
def token(options={})
# Esta funcion se llama desde Zoholib::AuthorizationRequest
# Ejecuta lo descrito en https://www.zoho.com/crm/developer/docs/api/access-refresh.html
@options[:query].merge!(grant_type: "authorization_code")
@options.merge!(:logger => @logger)
response=self.class.post('/token',@options)
JSON.parse(response.body,symbolize_names: true)
end
def token(options={})
# Esta funcion se llama desde Zoholib::AuthorizationRequest
# Ejecuta lo descrito en https://www.zoho.com/crm/developer/docs/api/access-refresh.html
@options[:query].merge!(grant_type: "authorization_code")
@options.merge!(:logger => @logger)
response=self.class.post('/token',@options)
JSON.parse(response.body,symbolize_names: true)
end
end
end
end
\ No newline at end of file
#require './lib/zoho_request'
module Zoholib
class RefreshRequest < ZohoRequest
module Wedoops
module Zoholib
class RefreshRequest < ZohoRequest
# Sin en algun momento se quiere evitar el encode de URL
# he aqui un truco
#query_string_normalizer proc { |query|
# query.map do |key, value|
# [value].flatten.map {|v| "#{key}=#{v}"}.join('&')
# end.join('&')
# }
# Sin en algun momento se quiere evitar el encode de URL
# he aqui un truco
def initialize(options={})
options.merge!(grant_type: "refresh_token")
@options={:query => options}
end
#query_string_normalizer proc { |query|
# query.map do |key, value|
# [value].flatten.map {|v| "#{key}=#{v}"}.join('&')
# end.join('&')
# }
def initialize(options={})
options.merge!(grant_type: "refresh_token")
@options={:query => options}
end
def get_token
self.class.post("/token",@options)
end
def get_token
self.class.post("/token",@options)
end
end
end
\ No newline at end of file
module Zoholib
module Zoho
module Wedoops
module Zoholib
class Response
......
# frozen_string_literal: true
module Zoholib
VERSION = '0.0.1b'
end
module Wedoops
module Zoholib
VERSION = '0.0.1b'
end
end
\ No newline at end of file
......@@ -7,167 +7,168 @@ require 'httparty'
#require './lib/authorization_request'
module Zoholib
class ZohoBasicClient
include HTTParty
base_uri 'https://www.zohoapis.com/crm/v2/'
def initialize(options={})
#Es un cliennte basico que trabaja a partir de refresh_tokens
@logger = ::Logger.new(STDOUT)
@logged_in = false
@options = options
@token = nil
end
def login
unless @options.has_key?(:refresh_token)
#En estos casos necesito mi refresh_token primero
auth_request=Zoholib::AuthorizationRequest.new(@options)
# Ojo esta opcion fuerza que siempre salga la pantalla
# de credenciales
result=auth_request.authorize({force_prompt: true})
@options.merge!(result)
#El refresh token habria que persisitirlo para
#evitar tener que cogerlo de nuevo
end
request= Zoholib::RefreshRequest.new(@options)
response=request.get_token
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
unless response[:access_token].nil?
@logged_in = true
@token = response[:access_token]
else
module Wedoops
module Zoholib
class ZohoBasicClient
include HTTParty
base_uri 'https://www.zohoapis.com/crm/v2/'
def initialize(options={})
#Es un cliennte basico que trabaja a partir de refresh_tokens
@logger = ::Logger.new(STDOUT)
@logged_in = false
@options = options
@token = nil
end
return @logged_in
end
def read_all(url,params={})
# ojo, maxrecords no tiene en cuenta cuantos registros se descaargan
# en cada ocasion por lo que puede devolver registros de mas
# como resto de la llamada anterior
page=1
maxrecords=-1
result = Hash.new
result[:data] = Array.new
params.delete(:page) if params.has_key?(:page)
if params.has_key?(:max_records)
maxrecords = params[:max_records]
params.delete(:max_records)
end
loop do
params.merge!(page: page)
response=read(url,params)
if response[:info][:more_records] == true
page+=1
result[:data].concat(response[:data])
break if maxrecords > 0 && result[:data].size >= maxrecords
def login
unless @options.has_key?(:refresh_token)
#En estos casos necesito mi refresh_token primero
auth_request=Zoholib::AuthorizationRequest.new(@options)
# Ojo esta opcion fuerza que siempre salga la pantalla
# de credenciales
result=auth_request.authorize({force_prompt: true})
@options.merge!(result)
#El refresh token habria que persisitirlo para
#evitar tener que cogerlo de nuevo
end
request= Zoholib::RefreshRequest.new(@options)
response=request.get_token
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
unless response[:access_token].nil?
@logged_in = true
@token = response[:access_token]
else
break
@logged_in = false
@token = nil
end
return @logged_in
end
return result
end
def read(url,params=nil)
self.login unless @logged_in
options = {}
options[:query] = params unless params.nil?
options.merge!(build_header)
def read_all(url,params={})
# ojo, maxrecords no tiene en cuenta cuantos registros se descaargan
# en cada ocasion por lo que puede devolver registros de mas
# como resto de la llamada anterior
page=1
maxrecords=-1
result = Hash.new
result[:data] = Array.new
params.delete(:page) if params.has_key?(:page)
if params.has_key?(:max_records)
maxrecords = params[:max_records]
params.delete(:max_records)
end
loop do
params.merge!(page: page)
response=read(url,params)
if response[:info][:more_records] == true
page+=1
result[:data].concat(response[:data])
break if maxrecords > 0 && result[:data].size >= maxrecords
else
break
end
end
return result
end
response=self.class.get("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
return response
end
def read(url,params=nil)
self.login unless @logged_in
options = {}
options[:query] = params unless params.nil?
options.merge!(build_header)
def write(url,data)
raise "Invalid JSON!" unless valid_json?(data)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body]=data
options.merge!(build_header)
response=self.class.post("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
response=self.class.get("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
return response
end
def update(url,data)
raise "Invalid JSON!" unless valid_json?(data)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body]=data
options.merge!(build_header)
response=self.class.put("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def write(url,data)
raise "Invalid JSON!" unless valid_json?(data)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body]=data
options.merge!(build_header)
response=self.class.post("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def query(coql)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body] = {:select_query => coql}.to_json
# options[:query]={scope:"ZohoCRM.coql.READ,ZohoCRM.modules.all"}
options[:logger]=@logger
options.merge!(build_header)
response=self.class.post("/coql",options)
#response=self.class.post("/coql?scope=ZohoCRM.modules.ALL,ZohoCRM.coql.read",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def update(url,data)
raise "Invalid JSON!" unless valid_json?(data)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body]=data
options.merge!(build_header)
response=self.class.put("/#{url}",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
def query_all(coql,params={})
# ojo, maxrecords no tiene en cuenta cuantos registros se descaargan
# en cada ocasion por lo que puede devolver registros de mas
# como resto de la llamada anterior
page=1
maxrecords=-1
result = Hash.new
result[:data] = Array.new
params.delete(:page) if params.has_key?(:page)
if params.has_key?(:max_records)
maxrecords = params[:max_records]
params.delete(:max_records)
def query(coql)
self.login unless @logged_in
options = {}
#Ojo, aqui tal vez deberiamos coprobar que viene con la forma :data => [:coleccion]
options[:body] = {:select_query => coql}.to_json
# options[:query]={scope:"ZohoCRM.coql.READ,ZohoCRM.modules.all"}
options[:logger]=@logger
options.merge!(build_header)
response=self.class.post("/coql",options)
#response=self.class.post("/coql?scope=ZohoCRM.modules.ALL,ZohoCRM.coql.read",options)
@logger.debug("#{__method__}:#{response.request.last_uri.to_s}")
response = JSON.parse(response.to_s, symbolize_names: true)
end
loop do
params.merge!(page: page)
response=self.query(coql)
return response if response[:status] == "error"
if response[:info][:more_records] == true
page+=1
result[:data].concat(response[:data])
break if maxrecords > 0 && result[:data].size >= maxrecords
else
break
def query_all(coql,params={})
# ojo, maxrecords no tiene en cuenta cuantos registros se descaargan
# en cada ocasion por lo que puede devolver registros de mas
# como resto de la llamada anterior
page=1
maxrecords=-1
result = Hash.new
result[:data] = Array.new
params.delete(:page) if params.has_key?(:page)
if params.has_key?(:max_records)
maxrecords = params[:max_records]
params.delete(:max_records)
end
loop do
params.merge!(page: page)
response=self.query(coql)
return response if response[:status] == "error"
if response[:info][:more_records] == true
page+=1
result[:data].concat(response[:data])
break if maxrecords > 0 && result[:data].size >= maxrecords
else
break
end
@logger.debug("#{result[:data].size} records")
@logger.debug("#{result[:data].last} ")
end
@logger.debug("#{result[:data].size} records")
@logger.debug("#{result[:data].last} ")
return result
end
return result
end
private
private
def build_header
{:headers => { "Authorization" => "Zoho-oauthtoken #{@token}"}}
end
def build_header
{:headers => { "Authorization" => "Zoho-oauthtoken #{@token}"}}
end
def valid_json?(json)
JSON.parse(json)
return true
rescue JSON::ParserError => e
return false
end
def valid_json?(json)
JSON.parse(json)
return true
rescue JSON::ParserError => e
return false
end
end
end
end
end
end
\ No newline at end of file
......@@ -7,619 +7,620 @@ require 'date'
require 'httparty'
#include ERB::Util
module Zoholib
class ZohoClient < ERB
attr_accessor :token, :scope, :auth_type, :client_id, :redirect_uri, :code
def initialize(options={})
@auth_type=nil
@user=nil
@pass=nil
@scope=nil
@life_token=nil
@client_id=nil
@client_secret=nil
@code=nil
@grant_type=nil
@access_token=nil
@refresh_token=nil
@api_domain=nil
@toke_type=nil
@expires_in=nil
@zapikey=nil
@redirect_uri=nil
@logger = Logger.new(STDOUT)
raise "Error constructing the class!" unless initialize_options(options)
@http = HTTP
module Wedoops
module Zoholib
class ZohoClient < ERB
attr_accessor :token, :scope, :auth_type, :client_id, :redirect_uri, :code
def initialize(options={})
@auth_type=nil
@user=nil
@pass=nil
@scope=nil
@life_token=nil
@client_id=nil
@client_secret=nil
@code=nil
@grant_type=nil
@access_token=nil
@refresh_token=nil
@api_domain=nil
@toke_type=nil
@expires_in=nil
@zapikey=nil
@redirect_uri=nil
@logger = Logger.new(STDOUT)
raise "Error constructing the class!" unless initialize_options(options)
@http = HTTP
.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache")
# .accept(:json)
@logger.info("Initialized")
end
def get_code
url="https://accounts.zoho.com/oauth/v2/auth?scope=#{@scope}&client_id=#{@client_id}&response_type=code&access_type=offline&redirect_uri=#{@redirect_uri}"
@logger.info(url)
@logger.info("#> Sending request....")
HTTP.follow
.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache")
# .accept(:json)
@logger.info("Initialized")
.get(url)
end
def token
#Dependiendo del tipo de autenticacion devolvere un tipo de token
case check_mode
when "apikey"
return @zapikey
when "oauth"
return @access_token
when "auth-token"
return @life_token
else
raise "Seems uninitialized!"
end
return nil
end
def token?
valid_token?
end
def grant_token!(token)
#Actualizo el codigo del grant token desde un callback de oauth probablemente
raise "Invalid token #{token}" unless /^\w{4}.\w{32}.\w{32}$/.match(token)
@logger.info("Grant Token updated! #{token}")
@code = token
get_refresh_token
persist_token
true
end
end
def get_code
url="https://accounts.zoho.com/oauth/v2/auth?scope=#{@scope}&client_id=#{@client_id}&response_type=code&access_type=offline&redirect_uri=#{@redirect_uri}"
@logger.info(url)
@logger.info("#> Sending request....")
HTTP.follow
.use(logging: {logger: @logger})
.timeout(connect: 15, read: 30)
.headers("cache-control" => "no-cache")
.get(url)
end
def token
#Dependiendo del tipo de autenticacion devolvere un tipo de token
case check_mode
when "apikey"
return @zapikey
when "oauth"
return @access_token
when "auth-token"
return @life_token
else
raise "Seems uninitialized!"
end
return nil
end
def token?
valid_token?
end
def grant_token!(token)
#Actualizo el codigo del grant token desde un callback de oauth probablemente
raise "Invalid token #{token}" unless /^\w{4}.\w{32}.\w{32}$/.match(token)
@logger.info("Grant Token updated! #{token}")
@code = token
get_refresh_token
persist_token
true
end
def refresh_token!
raise "Unsupported mode" unless check_mode == "oauth"
#if @refresh_token.nil?
# @logger.info("@refresh_token nulo, vamos a actualizar")
# get_refresh_token
# @logger.info("Actualizado el refresh token! ->#{@refresh_token}<-")
#end
def refresh_token!
raise "Unsupported mode" unless check_mode == "oauth"
#if @refresh_token.nil?
# @logger.info("@refresh_token nulo, vamos a actualizar")
# get_refresh_token
# @logger.info("Actualizado el refresh token! ->#{@refresh_token}<-")
#end
#En este supuesto acabo de inicializar con los basico de Oauth
# y quiero traerme la informacion con @code de un fichero
@logger.info("------------> Carga 1")
load_previous_token if token.nil?
@logger.info("TOKEN: #{token}")
@logger.info("auth_token: #{@auth_token}")
@logger.info("CODE: #{@code}")
show_current_options
@logger.info "Show VALID TOKEM DIRA:"
if token?
@logger.info("DICE QUE GUAY")
else
@logger.info("DICE QUE NO")
#get_refresh_token
# refresh_oauth_token
end
#En este supuesto acabo de inicializar con los basico de Oauth
# y quiero traerme la informacion con @code de un fichero
@logger.info("------------> Carga 1")
load_previous_token if token.nil?
@logger.info("TOKEN: #{token}")
@logger.info("auth_token: #{@auth_token}")
@logger.info("CODE: #{@code}")
show_current_options
@logger.info "Show VALID TOKEM DIRA:"
if token.nil?
@logger.info("TOken sigue siendo nulo")
if @code.nil?
@logger.info("------------> Carga 2!!!!")
#Tal vez habria que implementar un mecanismo para traer nuevos codes
raise "Unable to load it!!!" unless load_previous_token
end
# Si tengo un code debe ser que aun no se ha gastado
if get_authorization_token
@logger.info("Token refrescado #{@access_token}")
@http.headers("Authorization" => "Zoho-oauthtoken #{token}")
# Al persistirlo estamos grabando el refresh_token
#persist_token
#A la salida lo dejamos en blanco ya que no va a ser valido
#@refresh_token = nil
persist_token
return true
else
@logger.error("No ha sido posible refrescar el token")
return false
end
else
@logger.info("NO se refresca el token dado que todavia lo tenemos! #{token} : )")
true
end
end
def renew_life_token!(force=false)
raise "Unsupported mode" unless check_mode == "auth-token"
update_life_token!(force)
end
def execute(function,params=nil)
salida = case function
when "holamundo"
execute_function("https://www.zohoapis.com/crm/v2/functions/holamundo/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "holamundo2"
execute_function("https://www.zohoapis.com/crm/v2/functions/holamundo/actions/execute",{
auth_type: "apikey",
zapikey: "1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60"})
# ?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "getJSON"
execute_function("https://www.zohoapis.com/crm/v2/functions/getjson/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "getJSONParams"
execute_function("https://www.zohoapis.com/crm/v2/functions/getjsonparams/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60",params)
when "call"
#just standard function
#https://crm.zoho.com/crm/v2/functions/{api_name_of_function}/actions/execute?auth_type=apikey&zapikey={zapikey}
execute_function("https://crm.zoho.com/crm/v2/functions/{api_name_of_function}/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "read_api"
execute_function("https://www.zohoapis.com/crm/v2/Modules/")
when "adamo_address"
result=Array.new
(0..4).each do |page|
puts "Zoho-oauthtoken #{token}"
url="https://www.zohoapis.com/crm/v2/Adamo_Addresses?page=#{page}&sort_by=Adamo_ID"
#temp= HTTP.use(logging: {logger: @logger}).headers("Authorization" => "Zoho-oauthtoken #{token}").get(url)
temp=HTTParty.get(url,format: :json,:headers => {"Authorization" => "Zoho-oauthtoken #{token}"})
puts "......."
pp temp.body
puts "......"
result << temp
end
return result
when "get_settings"
url= "https://www.zohoapis.com/crm/v2/settings/modules"
params={:scope => @scope}
return get_params(url,params)
else
puts "Unknown function"
end
if token?
@logger.info("DICE QUE GUAY")
else
@logger.info("DICE QUE NO")
#get_refresh_token
# refresh_oauth_token
return normalize_output(salida)
end
if token.nil?
@logger.info("TOken sigue siendo nulo")
if @code.nil?
@logger.info("------------> Carga 2!!!!")
#Tal vez habria que implementar un mecanismo para traer nuevos codes
raise "Unable to load it!!!" unless load_previous_token
def execute_oauth(function)
url="https://www.zohoapis.com/crm/v2/functions/holamundo/actions/execute?auth_type=oauth"
end
def valid_json?(string)
!!JSON.parse(string)
rescue JSON::ParserError
false
end
private
def execute_function(url,params=nil)
# Ejecutamos una funcion GET con los parametors dados
# payload = {
# limit: 20,
# authtoken: @life_token,
# scope: "creatorapi",
# }
execute_url = url
payload = params
get_params(execute_url, params)
end
def get_refresh_token
@logger.info("#{__method__} con @refresh_token = #{@refresh_token} y grant_token (@code) = #{@code}")
#Proceso OAUTH para recibir un nuevo refresh_token para poder refrescar el token
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}"
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=refresh_token&code=#{@code}&redirect_uri=http://localhost:8000/auth/callback"
url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}&redirect_uri=#{@redirect_uri}"
res=post(url)
resultado = JSON.parse(res,:symbolize_names => true)
if resultado.has_key?(:error)
#pp resultado
@logger.error("Se ha detectado un error solicitando el refresh token. Arakiri.")
raise resultado[:error]
end
# Si tengo un code debe ser que aun no se ha gastado
if get_authorization_token
@logger.info("Token refrescado #{@access_token}")
@http.headers("Authorization" => "Zoho-oauthtoken #{token}")
# Al persistirlo estamos grabando el refresh_token
#persist_token
#A la salida lo dejamos en blanco ya que no va a ser valido
#@refresh_token = nil
persist_token
return true
else
@logger.error("No ha sido posible refrescar el token")
return false
end
else
@logger.info("NO se refresca el token dado que todavia lo tenemos! #{token} : )")
true
puts "-------RESULTADO DE GET REFRESH TOKEN----"
pp resultado
puts "..........."
@refresh_token = resultado[:refresh_token]
@token_type = resultado[:token_type]
@api_domain = resultado[:api_domain]
@access_token = resultado[:access_token]
@expires_in = (Time.new + resultado[:expires_in]).to_datetime
persist_token
return true
end
end
def renew_life_token!(force=false)
raise "Unsupported mode" unless check_mode == "auth-token"
update_life_token!(force)
end
def execute(function,params=nil)
salida = case function
when "holamundo"
execute_function("https://www.zohoapis.com/crm/v2/functions/holamundo/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "holamundo2"
execute_function("https://www.zohoapis.com/crm/v2/functions/holamundo/actions/execute",{
auth_type: "apikey",
zapikey: "1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60"})
# ?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "getJSON"
execute_function("https://www.zohoapis.com/crm/v2/functions/getjson/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "getJSONParams"
execute_function("https://www.zohoapis.com/crm/v2/functions/getjsonparams/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60",params)
when "call"
#just standard function
#https://crm.zoho.com/crm/v2/functions/{api_name_of_function}/actions/execute?auth_type=apikey&zapikey={zapikey}
execute_function("https://crm.zoho.com/crm/v2/functions/{api_name_of_function}/actions/execute?auth_type=apikey&zapikey=1003.7fb3bae78b241ff68541181c3b699cf1.983d91325ef11808acdc31d225fdca60")
when "read_api"
execute_function("https://www.zohoapis.com/crm/v2/Modules/")
when "adamo_address"
result=Array.new
(0..4).each do |page|
puts "Zoho-oauthtoken #{token}"
url="https://www.zohoapis.com/crm/v2/Adamo_Addresses?page=#{page}&sort_by=Adamo_ID"
#temp= HTTP.use(logging: {logger: @logger}).headers("Authorization" => "Zoho-oauthtoken #{token}").get(url)
temp=HTTParty.get(url,format: :json,:headers => {"Authorization" => "Zoho-oauthtoken #{token}"})
puts "......."
pp temp.body
puts "......"
result << temp
def get_authorization_token
@logger.info("#{__method__} con @refresh_token = #{@refresh_token} y grant_token (@code) = #{@code}")
#Proceso OAUTH para recibir un nuevo refresh_token para poder refrescar el token
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}"
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=refresh_token&code=#{@code}&redirect_uri=http://localhost:8000/auth/callback"
url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}&redirect_uri=#{@redirect_uri}"
res=post(url)
resultado = JSON.parse(res,:symbolize_names => true)
if resultado.has_key?(:error)
#pp resultado
@logger.error("Se ha detectado un error solicitando el authorization token. Arakiri.")
raise resultado[:error]
end
puts "-------RESULTADO DE GET AUTHORIZATION TOKEN----"
pp resultado
puts "..........."
@token_type = resultado[:token_type]
@api_domain = resultado[:api_domain]
@access_token = resultado[:access_token]
@expires_in = (Time.new + resultado[:expires_in]).to_datetime
# El code lo tengo que invalidar porque ya no es valido
@code = nil
persist_token
return true
end
def refresh_oauth_token
#params=auth_params("refresh_token")
@logger.info("Refrescando el token....")
url="https://accounts.zoho.com/oauth/v2/token?refresh_token=#{@refresh_token}&client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=refresh_token"
@logger.info("URL REFRESCO: #{url}")
# Pruebo sin pasar el secret
#url="https://accounts.zoho.com/oauth/v2/token?refresh_token=#{@refresh_token}&client_id=#{@client_id}&grant_type=refresh_token"
res=post(url)
resultado = JSON.parse(res,:symbolize_names => true)
if resultado.has_key?(:error)
pp resultado
@logger.error("Se ha detectado un error al refrescar el token.")
raise resultado[:error]
end
puts "-----------"
pp resultado
puts "..........."
@access_token = resultado[:access_token]
@token_type = resultado[:token_type]
@api_domain = resultado[:api_domain]
@expires_in = (Time.new + resultado[:expires_in]).to_datetime
return true
end
def update_life_token!(force=false)
#Recogemos el token para toda la vida
token_url="https://accounts.zoho.com/apiauthtoken/xml/create?SCOPE=#{@scope}&EMAIL_ID=#{@user}&PASSWORD=#{@pass}"
#A no ser que forcemos, devolvera true sin actualizar si el tokem es aun valido
unless force
if valid_token?
return true
end
end
response=@http.get(token_url).to_s
auth=/AUTHTOKEN=(?<token>\w{32})/.match(response)
result=/RESULT=(?<result>\w*)/.match(response)
if true?(result[:result])
@life_token = auth[:token]
else
return false
end
return result
when "get_settings"
url= "https://www.zohoapis.com/crm/v2/settings/modules"
params={:scope => @scope}
return get_params(url,params)
else
puts "Unknown function"
end
return normalize_output(salida)
end
def execute_oauth(function)
url="https://www.zohoapis.com/crm/v2/functions/holamundo/actions/execute?auth_type=oauth"
end
def valid_json?(string)
!!JSON.parse(string)
rescue JSON::ParserError
false
end
private
def execute_function(url,params=nil)
# Ejecutamos una funcion GET con los parametors dados
# payload = {
# limit: 20,
# authtoken: @life_token,
# scope: "creatorapi",
# }
execute_url = url
payload = params
get_params(execute_url, params)
end
def get_refresh_token
@logger.info("#{__method__} con @refresh_token = #{@refresh_token} y grant_token (@code) = #{@code}")
#Proceso OAUTH para recibir un nuevo refresh_token para poder refrescar el token
def auth_params(grant_type=@grant_type)
#osparams necesarios para una autenticaciton
if grant_type == "refresh_token"
#Ojo, el @refresh_token es efimero ya que solo se tiene en cuenta
# en el momento que se ejecuta get_refresh_token dentro de refresh_token
auth_params = {
refresh_token: @refresh_token,
client_id: @client_id,
client_secret: @client_secret,
grant_type: grant_type
}
else
auth_params = {
access_token: token,
client_id: @client_id,
client_secret: @client_secret,
grant_type: grant_type
}
end
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}"
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=refresh_token&code=#{@code}&redirect_uri=http://localhost:8000/auth/callback"
url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}&redirect_uri=#{@redirect_uri}"
res=post(url)
resultado = JSON.parse(res,:symbolize_names => true)
if resultado.has_key?(:error)
#pp resultado
@logger.error("Se ha detectado un error solicitando el refresh token. Arakiri.")
raise resultado[:error]
end
puts "-------RESULTADO DE GET REFRESH TOKEN----"
pp resultado
puts "..........."
@refresh_token = resultado[:refresh_token]
@token_type = resultado[:token_type]
@api_domain = resultado[:api_domain]
@access_token = resultado[:access_token]
@expires_in = (Time.new + resultado[:expires_in]).to_datetime
persist_token
return true
end
def get_authorization_token
@logger.info("#{__method__} con @refresh_token = #{@refresh_token} y grant_token (@code) = #{@code}")
#Proceso OAUTH para recibir un nuevo refresh_token para poder refrescar el token
end
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}"
#url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=refresh_token&code=#{@code}&redirect_uri=http://localhost:8000/auth/callback"
url="https://accounts.zoho.com/oauth/v2/token?client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=authorization_code&code=#{@code}&redirect_uri=#{@redirect_uri}"
res=post(url)
resultado = JSON.parse(res,:symbolize_names => true)
if resultado.has_key?(:error)
#pp resultado
@logger.error("Se ha detectado un error solicitando el authorization token. Arakiri.")
raise resultado[:error]
end
puts "-------RESULTADO DE GET AUTHORIZATION TOKEN----"
pp resultado
puts "..........."
@token_type = resultado[:token_type]
@api_domain = resultado[:api_domain]
@access_token = resultado[:access_token]
@expires_in = (Time.new + resultado[:expires_in]).to_datetime
# El code lo tengo que invalidar porque ya no es valido
@code = nil
persist_token
return true
end
def refresh_oauth_token
#params=auth_params("refresh_token")
@logger.info("Refrescando el token....")
url="https://accounts.zoho.com/oauth/v2/token?refresh_token=#{@refresh_token}&client_id=#{@client_id}&client_secret=#{@client_secret}&grant_type=refresh_token"
@logger.info("URL REFRESCO: #{url}")
# Pruebo sin pasar el secret
#url="https://accounts.zoho.com/oauth/v2/token?refresh_token=#{@refresh_token}&client_id=#{@client_id}&grant_type=refresh_token"
res=post(url)
resultado = JSON.parse(res,:symbolize_names => true)
if resultado.has_key?(:error)
pp resultado
@logger.error("Se ha detectado un error al refrescar el token.")
raise resultado[:error]
end
puts "-----------"
pp resultado
puts "..........."
@access_token = resultado[:access_token]
@token_type = resultado[:token_type]
@api_domain = resultado[:api_domain]
@expires_in = (Time.new + resultado[:expires_in]).to_datetime
return true
end
def update_life_token!(force=false)
#Recogemos el token para toda la vida
token_url="https://accounts.zoho.com/apiauthtoken/xml/create?SCOPE=#{@scope}&EMAIL_ID=#{@user}&PASSWORD=#{@pass}"
#A no ser que forcemos, devolvera true sin actualizar si el tokem es aun valido
unless force
if valid_token?
return true
def valid_token?
#Alguna consulta que nos verifique el que token es valido.
#Dependiendo del tipo de token tenemos distintas opciones
case check_mode
when "oauth"
valid_oauth_token?
when "apikey"
return @zapikey =! nil
when "auth-token"
return @life_token =! nil
else
raise "Error checking validity of token due an unexpected mode"
end
end
response=@http.get(token_url).to_s
auth=/AUTHTOKEN=(?<token>\w{32})/.match(response)
result=/RESULT=(?<result>\w*)/.match(response)
def valid_oauth_token?
@logger.info("Checking if the token is still valid...")
show_current_options
#options = nil
#if token.nil?
# puts "No hay token"
# begin
# options=options_from_json_file({:json_file=>'token.json',:auth_type=>'oauth'})
# rescue Exception => e
# @logger.info("No es posible tratar el fichero de token")
# return false
# end
# @logger.info("VAmos a inilizalizar las opciones")
# pp options
# initialize_options(options) unless options.nil?
if true?(result[:result])
@life_token = auth[:token]
else
#Aqui tenemos que ver si aun es valido
expires = @expires_in
expires = @expiry_time if expires.nil?
unless expires.nil?
expires = DateTime.strptime(expires.to_s,'%Q') if expires.kind_of?String
@logger.info("Comprobando si el token ha expirado")
puts DateTime.now < expires
puts "............................"
return DateTime.now < expires
else
@logger.info("Valid oauth token aun no esta implementado")
return true
end
return false
end
end
def auth_params(grant_type=@grant_type)
#osparams necesarios para una autenticaciton
if grant_type == "refresh_token"
#Ojo, el @refresh_token es efimero ya que solo se tiene en cuenta
# en el momento que se ejecuta get_refresh_token dentro de refresh_token
auth_params = {
refresh_token: @refresh_token,
client_id: @client_id,
client_secret: @client_secret,
grant_type: grant_type
}
else
auth_params = {
access_token: token,
client_id: @client_id,
client_secret: @client_secret,
grant_type: grant_type
}
def authorization_request
raise "Only available for OAuth" unless check_mode == "oauth"
#"https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.users.ALL&client_id={client_id}&response_type=code&access_type={"offline"or"online"}&redirect_uri={redirect_uri}"
end
end
def valid_token?
#Alguna consulta que nos verifique el que token es valido.
#Dependiendo del tipo de token tenemos distintas opciones
case check_mode
when "oauth"
valid_oauth_token?
when "apikey"
return @zapikey =! nil
when "auth-token"
return @life_token =! nil
else
raise "Error checking validity of token due an unexpected mode"
def get(url)
HTTP.use(logging: {logger: @logger}).headers("Authorization" => "Zoho-oauthtoken #{token}").accept(:json).get(url)
end
end
def valid_oauth_token?
@logger.info("Checking if the token is still valid...")
show_current_options
#options = nil
#if token.nil?
# puts "No hay token"
# begin
# options=options_from_json_file({:json_file=>'token.json',:auth_type=>'oauth'})
# rescue Exception => e
# @logger.info("No es posible tratar el fichero de token")
# return false
# end
# @logger.info("VAmos a inilizalizar las opciones")
# pp options
# initialize_options(options) unless options.nil?
#Aqui tenemos que ver si aun es valido
expires = @expires_in
expires = @expiry_time if expires.nil?
unless expires.nil?
expires = DateTime.strptime(expires.to_s,'%Q') if expires.kind_of?String
@logger.info("Comprobando si el token ha expirado")
puts DateTime.now < expires
puts "............................"
return DateTime.now < expires
else
@logger.info("Valid oauth token aun no esta implementado")
def get_params(url,payload)
if check_mode == "oauth"
@logger.info("Haciendo el get params de OAuth")
HTTP.use(logging: {logger: @logger}).headers("Authorization" => "Zoho-oauthtoken #{token}").accept(:json).get(url, :params => payload)
else
@logger.info("Haciendo el get params")
puts "........................."
pp @http
puts "........................."
@http.get(url, :params => payload).to_s
end
end
def true?(obj)
obj.to_s.downcase == "true"
end
def post_payload(callback_url, payload)
puts "Posting with payload"
#pp payload
@http.post(callback_url, json: payload)
rescue HTTP::Error
# handle exception
end
def post(url)
puts "Posting"
#pp payload
@http.post(url)
rescue HTTP::Error
# handle exception
end
def normalize_output(output)
raise "#{__method__} Invalid string. I can't normalize this crap!" unless valid_json?(output)
@logger.info "Normalizing..."
return Zoholib::Zoho::Response.new(output)
end
def sanitize(string)
util=ERB
return JSON.parse(util.json_escape)
end
# INIT CONTEXT
def initialize_options(options)
# Utilizamos options para configurar las distintas maneras de autenticarse
# Si las options tienen un json file extraeremos todas las opciones de ahi
options=options_from_json_file(options) if options.has_key?(:json_file)
@logger.info("Opciones en blanco") if options.empty?
raise "Invalid auth type" unless validate_auth_type(options)
raise "Invalid options" unless validate_options(options)
case check_mode
when "apikey"
@user=nil
@pass=nil
@scope=nil
@client_id=nil
@client_secret=nil
@code=nil
@grant_type=nil
@access_token=nil
@refresh_token=nil
@api_domain=nil
@toke_type=nil
@expires_in=nil
@zapikey=options[:zapikey]
@redirect_uri=nil
when "oauth"
@user=nil
@pass=nil
@scope=options[:scope]
@client_id=options[:client_id]
@client_secret=options[:client_secret]
@code=options[:code]
@grant_type=options[:grant_type]
@access_token=options[:access_token]
@refresh_token=options[:refresh_token]
@api_domain=nil
@toke_type=nil
@expires_in=options[:expiry_time]
@zapikey=nil
@redirect_uri=options[:redirect_uri]
when "auth-token"
@user=options[:user]
@pass=options[:pass]
@scope=options[:scope]
@client_id=nil
@client_secret=nil
@code=nil
@grant_type=nil
@access_token=nil
@refresh_token=nil
@api_domain=nil
@toke_type=nil
@expires_in=nil
@zapikey=nil
@redirect_uri=nil
else
raise "Unable to inilizalie!"
end
@scope=@scope.join(",") if @scope.kind_of?Array
return true
end
def options_from_json_file(options)
@logger.info("Parsing options from file...")
raise "Unable to find option json_file!" unless options.has_key?(:json_file)
begin
content = File.read(options[:json_file])
new_options=JSON.parse(content, :symbolize_names => true)
options.delete(:json_file)
new_options[:expires_in] = DateTime.strptime(new_options[:expiry_time].to_s,'%Q')
options = options.merge(new_options)
rescue Exception => e
puts e.backtrace
raise "Unable to read the json_file: #{e.message}"
end
#pp options
return options
end
def load_previous_token(previous_token="token.json")
@logger.info("Loading_previous_token...")
begin
content = File.read(previous_token)
new_options=JSON.parse(content, :symbolize_names => true)
@logger.info("LOADED FROM FILE:#{new_options} ")
#new_options[:expires_in] = DateTime.strptime(new_options[:expiry_time].to_s,'%Q')
initialize_options(new_options)
rescue Exception => e
puts e.backtrace
raise "Unable to load previous token: #{e.message}"
end
#pp options
return true
end
return false
end
def authorization_request
raise "Only available for OAuth" unless check_mode == "oauth"
#"https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.users.ALL&client_id={client_id}&response_type=code&access_type={"offline"or"online"}&redirect_uri={redirect_uri}"
end
def get(url)
HTTP.use(logging: {logger: @logger}).headers("Authorization" => "Zoho-oauthtoken #{token}").accept(:json).get(url)
end
def get_params(url,payload)
if check_mode == "oauth"
@logger.info("Haciendo el get params de OAuth")
HTTP.use(logging: {logger: @logger}).headers("Authorization" => "Zoho-oauthtoken #{token}").accept(:json).get(url, :params => payload)
else
@logger.info("Haciendo el get params")
puts "........................."
pp @http
puts "........................."
@http.get(url, :params => payload).to_s
def check_mode
#Check if im running in oauthv2 or auth-token
return @auth_type
end
end
def true?(obj)
obj.to_s.downcase == "true"
end
def post_payload(callback_url, payload)
puts "Posting with payload"
#pp payload
@http.post(callback_url, json: payload)
rescue HTTP::Error
# handle exception
end
def post(url)
puts "Posting"
#pp payload
@http.post(url)
rescue HTTP::Error
# handle exception
end
def normalize_output(output)
raise "#{__method__} Invalid string. I can't normalize this crap!" unless valid_json?(output)
@logger.info "Normalizing..."
return Zoholib::Zoho::Response.new(output)
end
def sanitize(string)
util=ERB
return JSON.parse(util.json_escape)
end
# INIT CONTEXT
def initialize_options(options)
# Utilizamos options para configurar las distintas maneras de autenticarse
# Si las options tienen un json file extraeremos todas las opciones de ahi
options=options_from_json_file(options) if options.has_key?(:json_file)
@logger.info("Opciones en blanco") if options.empty?
raise "Invalid auth type" unless validate_auth_type(options)
raise "Invalid options" unless validate_options(options)
case check_mode
when "apikey"
@user=nil
@pass=nil
@scope=nil
@client_id=nil
@client_secret=nil
@code=nil
@grant_type=nil
@access_token=nil
@refresh_token=nil
@api_domain=nil
@toke_type=nil
@expires_in=nil
@zapikey=options[:zapikey]
@redirect_uri=nil
def validate_auth_type(options)
#Comprobamos que forma parte de uno de los metodos de autenticacion soporteados
unless ["oauth","apikey","auth-token"].member?(options[:auth_type])
@logger.warn("Initializing with detault auth_type oauth")
@auth_type="oauth"
else
@auth_type = options[:auth_type]
end
return true
end
def required_options(auth_type=@auth_type)
#Dependiendo del tipo de autenticacion, indica cuales son las optciones requeridas
case auth_type
when "oauth"
@user=nil
@pass=nil
@scope=options[:scope]
@client_id=options[:client_id]
@client_secret=options[:client_secret]
@code=options[:code]
@grant_type=options[:grant_type]
@access_token=options[:access_token]
@refresh_token=options[:refresh_token]
@api_domain=nil
@toke_type=nil
@expires_in=options[:expiry_time]
@zapikey=nil
@redirect_uri=options[:redirect_uri]
return [:client_id,:client_secret,:scope]
#return [:client_id,:client_secret,:code,:grant_type,:scope]
when "apikey"
return [:zapikey]
when "auth-token"
@user=options[:user]
@pass=options[:pass]
@scope=options[:scope]
@client_id=nil
@client_secret=nil
@code=nil
@grant_type=nil
@access_token=nil
@refresh_token=nil
@api_domain=nil
@toke_type=nil
@expires_in=nil
@zapikey=nil
@redirect_uri=nil
return [:user,:pass,:scope]
else
raise "Unable to inilizalie!"
raise "#{__method__} Unknown auth_type #{auth_type}"
end
end
def validate_options(options)
# Comprueba que segun el metodo de autenticacion dado, nos han pasado todas la opciones necesarias
required_options.each do |key|
raise "#{__method__} Option #{key.to_s} not found!" unless options.has_key?(key)
raise "#{__method__} Option #{key.to_s} not found!" if options[key].nil?
end
@scope=@scope.join(",") if @scope.kind_of?Array
return true
end
def options_from_json_file(options)
@logger.info("Parsing options from file...")
raise "Unable to find option json_file!" unless options.has_key?(:json_file)
begin
content = File.read(options[:json_file])
new_options=JSON.parse(content, :symbolize_names => true)
options.delete(:json_file)
new_options[:expires_in] = DateTime.strptime(new_options[:expiry_time].to_s,'%Q')
options = options.merge(new_options)
rescue Exception => e
puts e.backtrace
raise "Unable to read the json_file: #{e.message}"
end
#pp options
return options
end
def load_previous_token(previous_token="token.json")
@logger.info("Loading_previous_token...")
begin
content = File.read(previous_token)
new_options=JSON.parse(content, :symbolize_names => true)
@logger.info("LOADED FROM FILE:#{new_options} ")
#new_options[:expires_in] = DateTime.strptime(new_options[:expiry_time].to_s,'%Q')
initialize_options(new_options)
rescue Exception => e
puts e.backtrace
raise "Unable to load previous token: #{e.message}"
end
#pp options
return true
end
def check_mode
#Check if im running in oauthv2 or auth-token
return @auth_type
end
def validate_auth_type(options)
#Comprobamos que forma parte de uno de los metodos de autenticacion soporteados
unless ["oauth","apikey","auth-token"].member?(options[:auth_type])
@logger.warn("Initializing with detault auth_type oauth")
@auth_type="oauth"
else
@auth_type = options[:auth_type]
end
return true
end
def required_options(auth_type=@auth_type)
#Dependiendo del tipo de autenticacion, indica cuales son las optciones requeridas
case auth_type
when "oauth"
return [:client_id,:client_secret,:scope]
#return [:client_id,:client_secret,:code,:grant_type,:scope]
when "apikey"
return [:zapikey]
when "auth-token"
return [:user,:pass,:scope]
else
raise "#{__method__} Unknown auth_type #{auth_type}"
end
end
def validate_options(options)
# Comprueba que segun el metodo de autenticacion dado, nos han pasado todas la opciones necesarias
required_options.each do |key|
raise "#{__method__} Option #{key.to_s} not found!" unless options.has_key?(key)
raise "#{__method__} Option #{key.to_s} not found!" if options[key].nil?
def validate_scope
# existen distintos tipos de scopes dependiendo del metodo
# auth-token
# scope="ZohoCreator/creatorapi"
# oauth
# scope="ZohoCRM.modules.ALL,ZohoCRM.settings.ALL"
# apikey
# scope=nil
return true
end
def persist_token
expiry_time = @expires_in.strftime("%Q") if @expires_in.kind_of?DateTime
token_information = {
:client_id =>@client_id,
:client_secret => @client_secret,
:scope => @scope,
:access_token => token,
:code => @code,
:expiry_time => expiry_time,
:grant_type => @grant_type,
:redirect_uri => @redirect_uri,
:refresh_token => @refresh_token,
:auth_type => 'oauth'
}
f=File.new("token.json","w+")
f.print(token_information.to_json)
f.close
end
return true
end
def validate_scope
# existen distintos tipos de scopes dependiendo del metodo
# auth-token
# scope="ZohoCreator/creatorapi"
# oauth
# scope="ZohoCRM.modules.ALL,ZohoCRM.settings.ALL"
# apikey
# scope=nil
return true
end
def persist_token
expiry_time = @expires_in.strftime("%Q") if @expires_in.kind_of?DateTime
token_information = {
:client_id =>@client_id,
:client_secret => @client_secret,
:scope => @scope,
:access_token => token,
:code => @code,
:expiry_time => expiry_time,
:grant_type => @grant_type,
:redirect_uri => @redirect_uri,
:refresh_token => @refresh_token,
:auth_type => 'oauth'
}
f=File.new("token.json","w+")
f.print(token_information.to_json)
f.close
end
def show_current_options
@logger.info("auth_type : #{@auth_type}")
@logger.info("user : #{@user}")
@logger.info("pass : #{@pass}")
@logger.info("scope : #{@scope}")
@logger.info("life_token : #{@life_token}")
@logger.info("client_id : #{@client_id}")
@logger.info("client_secret : #{@client_secret}")
@logger.info("code : #{@code}")
@logger.info("grant_type : #{@grant_type}")
@logger.info("access_token : #{@access_token}")
@logger.info("refresh_token : #{@refresh_token}")
@logger.info("api_domain : #{@api_domain}")
@logger.info("token_type : #{@token_type}")
@logger.info("expires_in : #{@expires_in}")
@logger.info("expiry_time : #{@expiry_time}")
@logger.info("zapikey : #{@zapikey}")
@logger.info("redirect_uri : #{@redirect_uri}")
def show_current_options
@logger.info("auth_type : #{@auth_type}")
@logger.info("user : #{@user}")
@logger.info("pass : #{@pass}")
@logger.info("scope : #{@scope}")
@logger.info("life_token : #{@life_token}")
@logger.info("client_id : #{@client_id}")
@logger.info("client_secret : #{@client_secret}")
@logger.info("code : #{@code}")
@logger.info("grant_type : #{@grant_type}")
@logger.info("access_token : #{@access_token}")
@logger.info("refresh_token : #{@refresh_token}")
@logger.info("api_domain : #{@api_domain}")
@logger.info("token_type : #{@token_type}")
@logger.info("expires_in : #{@expires_in}")
@logger.info("expiry_time : #{@expiry_time}")
@logger.info("zapikey : #{@zapikey}")
@logger.info("redirect_uri : #{@redirect_uri}")
end
end
end
end
require 'httparty'
require 'json'
module Zoholib
class ZohoRequest
include HTTParty
#debug_output $stdout
base_uri "https://accounts.zoho.com/oauth/v2/"
#https://accounts.zoho.com/oauth/v2/auth?
#https://accounts.zoho.com/oauth/v2/token?
headers 'Content-Type' => 'application/json'
attr_reader :subdomain, :uri
module Wedoops
module Zoholib
class ZohoRequest
include HTTParty
#debug_output $stdout
base_uri "https://accounts.zoho.com/oauth/v2/"
#https://accounts.zoho.com/oauth/v2/auth?
#https://accounts.zoho.com/oauth/v2/token?
headers 'Content-Type' => 'application/json'
attr_reader :subdomain, :uri
end
end
end
\ No newline at end of file
......@@ -5,7 +5,7 @@ require 'zoholib'
RSpec.configure do |conf|
conf.before(:all) do
Zoholib.configure do |config|
Wedoops::Zoholib.configure do |config|
puts "Trying to config"
config.client_id = "client_id"
config.client_secret = "client_secret"
......
require 'spec_helper'
require 'stringio'
RSpec.describe Zoholib do
RSpec.describe Wedoops::Zoholib do
it 'has a version number' do
expect(Zoholib::VERSION).not_to be nil
expect(Wedoops::Zoholib::VERSION).not_to be nil
end
it 'does something useful' do
......@@ -12,23 +12,23 @@ RSpec.describe Zoholib do
describe 'Configuration' do
it 'The configuration shuld be a Zoholib::Configuration' do
expect(Zoholib.configuration).to be_a_kind_of(Zoholib::Configuration)
expect(Wedoops::Zoholib.configuration).to be_a_kind_of(Wedoops::Zoholib::Configuration)
end
it 'The client_id is a string' do
expect(Zoholib.configuration.client_id).to be_an(String)
expect(Wedoops::Zoholib.configuration.client_id).to be_an(String)
end
it 'The client_secret is a string' do
expect(Zoholib.configuration.client_secret).to be_an(String)
expect(Wedoops::Zoholib.configuration.client_secret).to be_an(String)
end
it 'The scopes is a string' do
expect(Zoholib.configuration.scope).to be_an(String)
expect(Wedoops::Zoholib.configuration.scope).to be_an(String)
end
it 'The refresh_token is a string' do
expect(Zoholib.configuration.refresh_token).to be_an(String)
expect(Wedoops::Zoholib.configuration.refresh_token).to be_an(String)
end
end
end
\ No newline at end of file
......@@ -6,7 +6,7 @@ require 'zoholib/version'
Gem::Specification.new do |spec|
spec.name = 'zoholib'
spec.version = Zoholib::VERSION
spec.version = Wedoops::Zoholib::VERSION
spec.date = '2020-04-25'
spec.authors = ['Wedoops.io']
spec.email = 'wedoops@wedoops.io'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment