uninitialized constant "controllername::modulename" TableauServer - ruby-on-rails

Im trying to test the tableau_trusted.rb example for trusted authentication for tableau server in Ruby on rails but I keep getting the error "uninitialized constantTableauTrustedsController::TableauTrustedInterface", this is my code:
tableautrusteds_controller.rb
class TableauTrustedsController < ApplicationController
include TableauTrustedInterface
def index
tabserver = 'xxxxx'
tabuser = 'test'
tabpath = 'views/Tableau_DW1/General?:iid=1'
tabparams = ':embed=yes&:toolbar=no'
ticket = tableau_get_trusted_ticket(tabserver, tabuser, request.remote_ip)
if ticket != "-1"
url = "http://#{tabserver}/trusted/#{ticket}/#{tabpath}?#{tabparams}"
redirect_to url
return
end
render :status => 403, :text => "Error with request"
end
end
module TableauTrustedInterface
require 'net/http'
require 'uri'
# the client_ip parameter isn't necessary to send in the POST unless you have
# wgserver.extended_trusted_ip_checking enabled (it's disabled by default)
def tableau_get_trusted_ticket(tabserver, tabuser, client_ip)
post_data = {
"username" => tabuser,
"client_ip" => client_ip
}
response = Net::HTTP.post_form(URI.parse("http://#{tabserver}/trusted"), post_data)
case response
when Net::HTTPSuccess
return response.body.to_s
else
return "-1"
end
end
end
I have changed the line "include TableauTrustedInterface" to "extend TableauTrustedInterface" but it didn't work.
Also, The URL I put in the browser is
http://localhost:3000/tableautrusteds/index, I use get 'tableautrusteds/index' in routes.rb.
I don't really know if that is important but some people ask me for this.
I am little bit new in rails so any help will be very appreciated.

I fixed my problem, if anybody was having a similar issue here is my code
module TableauTrustedInterfaces
require 'net/http'
require 'uri'
# the client_ip parameter isn't necessary to send in the POST unless you have
# wgserver.extended_trusted_ip_checking enabled (it's disabled by default)
def tableau_get_trusted_ticket(tabserver, tabuser, client_ip)
post_data = {
"username" => tabuser,
"client_ip" => client_ip
}
response = Net::HTTP.post_form(URI.parse("http://#{tabserver}/trusted"), post_data)
case response
when Net::HTTPSuccess
return response.body.to_s
else
return "-1"
end
end
end
class TableauTrustedController < ApplicationController
include TableauTrustedInterfaces
def index
tabserver = 'xxxxx'
tabuser = 'test'
tabpath = 'views/Tableau_DW1/General?:iid=1'
tabparams = ':embed=yes&:toolbar=no'
ticket = tableau_get_trusted_ticket(tabserver, tabuser, request.remote_ip)
if ticket != "-1"
url = "http://#{tabserver}/trusted/#{ticket}/#{tabpath}?#{tabparams}"
redirect_to url
return
end
render json: {}, status: :forbidden
end
end
In order to use the module it needs to be declared before the class. Also, and very important I changed the name of the file to tableau_trusted_controler.rb because the snake case that rails uses.

Related

Best practices for Ruby on Rails service

I'm writing some mobile otp validation service and below is my service class
require 'nexmo'
class NexmoServices
def initialize api_key = nil, api_secret = nil, opts = {}
api_key = api_key || Rails.application.secrets.nexmo_api_key
api_secret = api_secret || Rails.application.secrets.nexmo_secret_key
#nexmo_client = Nexmo::Client.new(
api_key: api_key,
api_secret: api_secret,
code_length: 6
)
#brand = 'CryptoShop'
end
def send_verification_code opts
#nexmo_client.verify.request(number: opts[:number], brand: #brand)
end
def check_verification_code opts
#nexmo_client.verify.check(request_id: opts[:request_id], code: opts[:verification_code])
end
def cancel_verification_code opts
#nexmo_client.verify.cancel(opts[:request_id])
end
end
in the controller i'm calling the service methods like below
class NexmoController < ApplicationController
def send_verification_code
response = NexmoServices.new.send_verification_code params[:nexmo]
if response.status == '0'
render json: response.request_id.to_json
else
render json: response.error_text.to_json
end
end
def cancel_verification_code
response = NexmoServices.new.cancel_verification_code params[:nexmo]
if response.status == '0'
render json: response.to_json
else
render json: response.error_text.to_json
end
end
end
I have read that usually there will be call method inside service class and controller will call that. service method call will take care of the rest.
My case im instantiating service objects for all the methods if you see my controller(NexmoService.new).
is it correct??? I want to know the best practise must be followed in this scenario.
Thanks,
Ajith

How to send a get to a server and wait a get in my app in Ruby on Rails

I am using Zapier to search some information in google sheets. I used Webhocks to send a GET to his server with a JSON information. The response of GET is an "OK" and I can't custom this.
So, they will execute a task, find what a I want and return a value, but the response must be a GET in my server, and I don't know how to intercept this response in my route.
I'm trying to study Rails Rack to intercept de request in my app, but I don't know how to send the response to the event that sent the first GET.
How is my middleware:
class DeltaLogger
def initialize app
#app = app
end
def call env
Rails.logger.debug "#{env['QUERY_STRING']}"
#status, #headers, #response = #app.call(env)
[#status, #headers, #response]
end
end
Thanks!
Example
So, to get the value returned from Zapier, I created two routes and a global class cache.
class Zapier
require 'httparty'
def initialize
#answer = ""
#id = 0
end
def request(uri, task)
last_event = Event.last
puts last_event.inspect
if last_event.nil?
last_id = 0
else
last_id = last_event.event_id
end
event_id = last_id + 1
Event.find_or_create_by(event_id: event_id)
result = HTTParty.post(uri.to_str,
:body => {id: event_id, task: task}.to_json,
:headers => {'content-Type' => 'application/json'})
#answer = ""
#id = event_id
end
def response(event_id, value)
if event_id != #id
#answer = ""
else
#answer = value
end
end
def get_answer
#answer
end
end
And my controller:
class ZapierEventsController < ApplicationController
require 'zapier_class'
before_action :get_task, only: [:get]
before_action :get_response, only: [:set]
##zapier ||= Zapier.new
def get
##zapier.request('https://hooks.zapier.com',#task)
sleep 10 #Wait for response
#value = ##zapier.get_answer
render json: { 'value': #value }, status:
end
def set
##zapier.response(#id, #value)
render json: { 'status': 'ok' }, status: 200
end
def get_task
#task = params["task"]
end
def get_response
#id = Integer(params["id"])
#value = params["value"]
end
end
Now i have to make a Task Mananger

Define a params in a variable

I would know how define a params in a variable to use it in another method
In my controller i have result page and contact page, i want store the search params from result page in variables and get them in my contact page method to not duplicate form fields
My result page
def result
if params[:room_type].present? && params[:location].present? && params[:nb_piece].present?
#biens = Bien.near(params[:location], 1, units: :km).where(room_type: params[:room_type], nb_piece: params[:nb_piece])
end
#users = User.where(id: #biens.reorder(:user_id).pluck(:user_id), payer: true) || User.where(id: #biens.reorder(:user_id).pluck(:user_id), subscribed: true)
end
I want store this params in my other method,like that i will need to ask only email and phone in my form
def contact
wufoo(params[:location], params[:room_type], params[:nb_piece], params[:email], params[:phone])
end
My wufoo
def wufoo(adresse, type, pieces, email, phone)
require "net/http"
require "uri"
require "json"
base_url = 'https://wako94.wufoo.com/api/v3/'
username = 'N5WI-FJ6V-WWCG-STQJ'
password = 'footastic'
uri = URI.parse(base_url+"forms/m1gs60wo1q24qsh/entries.json")
request = Net::HTTP::Post.new(uri.request_uri)
request.basic_auth(username, password)
request.set_form_data(
'Field7' => adresse,
'Field9' => type,
'Field12' => email,
'Field11' => phone,
'Field8' => pieces
)
response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme =='https'){
|http|http.request(request)
}
puts JSON.pretty_generate(JSON[response.body])
end
It depends on how a user goes from search to contact. I assume that the contact form is linked off the search, and that they want to contact you regarding the information in the last search.
A simple method here would be to store the last search within the session, and just reference that.
def search
store_params_in_session
# .. your search logic here
end
def contact
last_search = session[:last_search]
if last_search.blank?
# .. some error handling if no search is available
return
end
wufoo(last_search[:location], #.. you get the idea
end
private
def store_params_in_session
session[:last_search] = {
location: params[:location],
# .. more params here
}

Updating Rails 5 Initializer with Devise User Parameters

I thought I was getting closer to wrapping my head around Rails until this challenge. I have an initializer agilecrm.rb - content show below. I am using AgileCRM Ruby code to try and connect my app with AgileCRM system. When using the code below, with the test Create Contact array at the bottom, it successfully creates a contact in my AgileCRM account, so I know at least this part works. What I need to do is create a new AgileCRM user every time I create a new Devise user. I have a feeling that I am looking at this the wrong way and probably need a controller for this, but this is not completely foreign to me, but I still can't figure out when way to go. Thank you.
config/initializers/agilecrm.rb
require 'net/http'
require 'uri'
require 'json'
class AgileCRM
class << self
def api_key=(key)
##api_key = key
end
def domain=(d)
##domain = d
end
def email=(email)
##email = email
end
def api_key
##api_key
end
def domain
##domain
end
def email
##email
end
def request(method, subject, data = {})
path = "/dev/api/#{subject}"
case method
when :get
request = Net::HTTP::Get.new(path)
when :post
request = Net::HTTP::Post.new(path)
request.body = data.to_json
when :put
request = Net::HTTP::Put.new(path)
request.body = data.to_json
when :delete
request = Net::HTTP::Delete.new(path)
else
raise "Unknown method: #{method}"
end
uri = URI.parse("https://#{domain}.agilecrm.com")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
request.basic_auth AgileCRM.email, AgileCRM.api_key
response = http.request(request)
response.body
end
end
end
AgileCRM.api_key = '*******'
AgileCRM.domain = '*******'
AgileCRM.email = '*******'
# ======================Create Contact====================================
contact_data = '{
"star_value": "4",
"lead_score": "92",
"tags": [
"Lead",
"Likely Buyer"
],
"properties": [
{
"type": "SYSTEM",
"name": "first_name",
"value": "John"
}
]
}'
parsed_contact_data = JSON.parse(contact_data)
print(AgileCRM.request :post, 'contacts', parsed_contact_data)
You might want to move this logic into your User model, and have a after_save hook to push data to agilecrm. Assuming that the Devise user model is called User :
class User < ApplicationRecord
...
after_save :sync_to_agilecrm
def sync_to_agilecrm
# your agilecrm api calls go here
...
end
end
The above should do what you are trying to achieve.

Unfuddle API get accounts info

I'm trying to get the account info from Unfuddle API using ActiveResource
The url is http://mydomain.unfuddle.com/api/v1/account
this is my ActiveResource class
class Account < ActiveResource::Base
self.collection_name = "account"
self.site = "https://mydomain.unfuddle.com/api/v1"
self.user = "me"
self.password = "pass"
end
if I try getting my account info with Account.all I'll get an empty array but if I try this
require 'net/https'
UNFUDDLE_SETTINGS = {
:subdomain => 'mydomain',
:username => 'me',
:password => 'pass',
:ssl => true
}
http = Net::HTTP.new("#{UNFUDDLE_SETTINGS[:subdomain]}.unfuddle.com",UNFUDDLE_SETTINGS[:ssl] ? 443 : 80)
if UNFUDDLE_SETTINGS[:ssl]
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
begin
request = Net::HTTP::Get.new('/api/v1/account')
request.basic_auth UNFUDDLE_SETTINGS[:username], UNFUDDLE_SETTINGS[:password]
response = http.request(request)
if response.code == "200"
puts response.body
else
puts "HTTP Status Code: #{response.code}."
end
rescue => e
puts e.message
end
I get my account information , any ideas why the ActiveResource approach isn't working ?
**UPDATE
I forgot to specify that I had this issue https://github.com/rails/rails/issues/2318 and I use erikkallens hack .
It seems to be this issue https://github.com/rails/rails/issues/2318 , I tried vaskas solution but it didn't work by default I had to modify it.
class Account < ActiveResource::Base
self.collection_name = "account"
self.site = "https://mydomain.unfuddle.com/api/v1"
self.user = "me"
self.password = "pass"
self.format = AccountXMLFormatter.new
end
class AccountXMLFormatter
include ActiveResource::Formats::XmlFormat
def decode(xml)
[account: ActiveResource::Formats::XmlFormat.decode(xml)]
end
end

Resources