I am trying to get my new application integrated with JIRA for management of our customer's support tickets. What I had envisioned the system doing was in a before_filter gathering a user's account from within JIRA - from that I can pull up a list of accounts and what not, and if they don't have one then we create one based on their details in the Rails application. Thing is I'm having major issues doing things like removing the user from the jira-users group and adding them to a separate group I have for customers called customer-support. This is the code I have currently:
def current_jira_user
# Fetch the current user in JIRA, if we don't exist, create it!
user_try = #jira.request :get_user do |soap|
soap.body = { :token => #token, :username => "#{current_user.username}" }
end
if user_try.to_hash[:get_user_response][:get_user_return][:href].nil?
# We need to create the user
#jira.request :create_user do |soap|
soap.body = {
:token => #token,
:username => "#{current_user.username}",
:password => UUID.new.to_s,
:fullName => current_user.full_name,
:email => "noreply#XXXXX.XXX" #this is such a hack to get around JIRA's "you've got an account" email
}
end
new_user = RemoteUser.find(current_user.username)
#jira.request :remove_user_from_group do |soap|
soap.body = { :token => #token, :group => RemoteGroup.find('jira-users'), :ruser => new_user }
end
#jira.request :add_user_to_group do |soap|
soap.body = { :token => #token, :group => RemoteGroup.find('customer-support'), :ruser => new_user }
end
new_user[:email] = current_user.email
#jira.request :update_user do |soap| # change their email to the valid one
soap.body = { :token => #token, :ruser => new_user }
end
new_user
else
user_try.to_hash[:get_user_response][:get_user_return]
end
end
def verify_jira_connection
# Verify that we can reach the JIRA instance
#jira = Savon::Client.new do
wsdl.document = JIRA_SOAP_URI
end
#jira.http.read_timeout = 300
#jira.http.auth.ssl.verify_mode = :none
#auth = #jira.request :login do |soap|
soap.body = { :username => JIRA_LOGIN, :password => JIRA_PASSWORD }
end
#token = #auth.to_hash[:login_response][:login_return]
end
## REMOTE CLASSES
class RemoteUser
include Savon::Model
client do
http.headers["Pragma"] = "no-cache"
http.auth.ssl.verify_mode = :none
end
namespace "http://beans.soap.rpc.jira.atlassian.com"
endpoint JIRA_SOAP_URI
basic_auth JIRA_LOGIN, JIRA_PASSWORD
actions :get_user
def self.find(username)
get_user(:username => username).to_hash
end
end
class RemoteGroup
include Savon::Model
client do
http.headers["Pragma"] = "no-cache"
http.auth.ssl.verify_mode = :none
end
namespace "http://beans.soap.rpc.jira.atlassian.com"
endpoint JIRA_SOAP_URI
basic_auth JIRA_LOGIN, JIRA_PASSWORD
actions :get_group
def self.find(group)
get_group(:groupName => group).to_hash
end
end
Users are created just fine, but when I get to the removeUserFromGroup call, I get (soapenv:Server.userException) com.atlassian.jira.rpc.exception.RemoteValidationException: group name cannot be null, needs a value. Using the Jira4R gem is out thanks to our using Ruby 1.9.2. Any help is appreciated. Thanks!
Maybe you need to explicitly send the name?
:group => RemoteGroup.find('jira-users').name
instead of this
:group => RemoteGroup.find('jira-users')
If you were willing to do some rewriting, you could try using a Ruby 1.9-compatible fork of jira4r
Related
I read previous possible questions that may have the answer but that not what I asked for.
First of all I am start to use test. However I already successful setup Omniauth-facebook for my App but still like to go back and test.
-sessions_controller.rb
class SessionsController < ApplicationController
def new
#title= 'Sign In'
end
def create
auth = request.env["omniauth.auth"]
user = User.from_omniauth(auth)
session[:user_id] = user.id
if params.permit[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
refresh_to root_path, :ma_notice => "Logged in"
rescue
redirect_to root_path, :alert=> "Authentication failed, please try again."
end
def destroy
#session[:user_id] = nil
cookies.delete(:auth_token)
refresh_to root_path, :ma_notice => "Logged Out"
end
def failure
ma_log "Authentication failed, please try again."
redirect_to root_path, :alert=> "Authentication failed, please try again."
end
end
-app/models/user.rb
class User
....
....
def self.from_omniauth(auth)
where(auth.slice(:uid, :provider, :email)).first_or_create do |user|
case auth.provider
when 'identity'
identity = Identity.find auth.uid
user.code = identity.code
user.email = identity.email
else
user.email = auth.info.email
user.uid = auth.uid
user.provider = auth.provider
user.code = auth.info.name
user.role = "M"
end
end
end
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
So what I did
Test routes (Its seem simple but sometime I might forgot because I changing from dynamic route to fixed route as required in rails 5.2)
-test/integration/authen_test.rb
require 'test_helper'
class RoutesTest < ActionController::TestCase
test 'facebook login' do
assert_routing '/auth/facebook/callback', {controller: 'sessions', action: 'create',provider: 'facebook'}
end
test 'facebook login post' do
assert_routing({path: '/auth/facebook/callback', method: 'post'},{controller: 'sessions', action: 'create' ,provider: 'facebook'})
end
end
I want to test if facebook accept login and return call back.
-test/models/user_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "Facebook validation" do
auth = {provider: :facebook, FACEBOOK_API: "111111111111111", FACEBOOK_KEY: "11111111111111111111111111111111"}
user = User.from_omniauth(auth)
puts user
assert_not nil
end
end
Problem: It's always green even change FACEBOOK_API. I found the user from puts as well. It's seem like user.from _omniauth already gone to facebook and get info using FACEBOOK_API from .env not one I provided. Then how I can test if it really connected with facebook.
The same with this related test. It's always green in any FACEBOOI_API. That won't work as well.
View Test. I like to test if no facebook login the system or not. The login would display accordingly. Still have no idea as stuck with Q.2 perhap someone could share how you do the test.
To Setup Integration Testing-Omniauth as documented
You can turn on "test mode" for OmniAuth like so:
OmniAuth.config.test_mode = true Once you have enabled test mode, all
requests to OmniAuth will be short circuited to use the mock
authentication hash as described below. A request to /auth/provider
will redirect immediately to /auth/provider/callback.
Then said
OmniAuth.config.add_mock(:twitter, {:uid => '12345'})
OK but where to put that code to turn on
so I assumed the only one is
-config/initializer/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :identity,
:fields => [:code, :email],
:on_failed_registration=> lambda { |env|
IdentitiesController.action(:new).call(env)
}
provider :facebook, ENV['FACEBOOK_API'], ENV['FACEBOOK_KEY']
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:facebook] = :invalid_credentials
end
Here I used test from related question but used my method :create.
It didn't do anything than green, even changed .test_mode = false
-test/integration/sessions_controller_test.rb
require 'test_helper'
class SessionsControllerTest < ActionController::TestCase
test '#signup_success' do
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
'provider' => 'facebook',
'uid' => '123451234512345',
'info' => {'email' => 'testuser#testmail.com', 'name' => 'test', 'image' => ''}
})
request.env['omniauth.env'] = OmniAuth.config.mock_auth[:facebook]
get :create
end
end
You can use omniauth test helpers. Here is the link:
https://github.com/omniauth/omniauth/wiki/Integration-Testing
Setup Mock Auth:
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
:provider => 'facebook',
:uid => '123545'
# etc.
})
What i did and what worked for me was setting up mocks in my spec_helper file for various scenarios.
OmniAuth.config.test_mode = true
omniauth_hash = { 'provider' => 'twitter',
'uid' => '12345',
'info' => {
'name' => 'test',
'email' => 'test#test.com',
'nickname' => 'testnick'
},
'extra' => {
'raw_info' =>
{
'location' => 'Coralvilleo'
}
}
}
omniauth_hash_fb = { 'provider' => 'facebook',
'uid' => '12345',
'info' => {
'name' => 'test',
'email' => 'test#testsomething.com'
},
'extra' => {'raw_info' =>
{ 'location' => 'Chicago'
}
}
}
omniauth_hash_fail = { 'provider' => 'facebook',
'uid' => '12345',
'info' => {
},
'extra' => {'raw_info' =>
{ 'location' => 'Chicago'
}
}
}
omniauth_hash_fail_2 = { 'provider' => 'facebook',
'uid' => '12345',
'info' => {
},
'extra' => {'raw_info' =>
{ 'location' => 'Chicago'
}
}
}
omniauth_hash_fail_complete = { 'provider' => 'twitter'}
OmniAuth.config.add_mock(:twitter, omniauth_hash)
OmniAuth.config.add_mock(:facebook, omniauth_hash_fb)
OmniAuth.config.add_mock(:facebook_fail, omniauth_hash_fail)
OmniAuth.config.add_mock(:twitter_fail, omniauth_hash_fail_2)
Then using these methods in my rspec tests for controller like so.
it 'should successfully create a user with twitter' do
request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:twitter]
expect {
post :twitter, provider: :twitter
}.to change{ User.count }.by(1)
end
it 'should redirect the user to the root url with twitter' do
request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:twitter]
post :twitter, provider: :twitter
response.should redirect_to root_path
end
name of the mocks to be specified and linked to what we specified in the helper.
OmniAuth.config.mock_auth[name of the mock you specified in spec helper].
I have tried all the tricks in the book and all the possible solution in stack over flow.But still couldn't figure out the problem. The program pauses at the call back initiated stage and shows faraday connection : timed out. I have the following code:
gem 'omniauth', '~> 1.3', '>= 1.3.1'
gem 'omniauth-facebook'
Routes.rb
devise_for :users,
:path => '',
:path_names => {:sign_in => 'login', :sign_out => 'logout', :edit => 'profile' },
:controllers => {:omniauth_callbacks => 'omniauth_callbacks'}
/Controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"].except("extra")
redirect_to new_user_registration_url
end
end
end
/user.rb
class User < ApplicationRecord
def self.from_omniauth(auth)
user = User.where(email: auth.info.email).first
if user
return user
else
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.image = auth.info.image
user.password = Devise.friendly_token[0,20]
user.firstname = auth.info.first_name
user.lastname = auth.info.last_name
user.phonenumber == '0000000000'
user.tc == true
user.year == true
end
end
end
end
/devise.rb
config.omniauth:facebook,ENV['FACEBOOK_ID'],ENV['FACEBOOK_SECRET'],scope:'email',info_fields:'email,first_name,last_name'
I update apllication from rails 2 to rails 3.
And I rewrite routes with resources. How to write route to this actions:
def delete_attachment
#object = Article.find(params[:id])
attachment = Attachment.find(params['attachment_id'])
attachment.attachment = nil
attachment.destroy
redirect_to :action => 'edit', :id => #object.id
end
def edit_attachment
#object = Article.find(params[:id])
attachment = Attachment.find(params['attachment_id'])
attachment.title = params['attachment_title']
attachment.description = params['attachment_description']
attachment.save
redirect_to :action => 'edit', :id => #object.id
end
def add_attachment
#object = Article.find(params[:id])
attachment = Attachment.new
attachment.attachment = params['attachment_file']
attachment.title = params['attachment_title']
attachment.description = params['attachment_description']
attachment.article_id = #object.id
attachment.save
params['attachment_title'] = nil
params['attachment_description'] = nil
redirect_to :action => 'edit', :id => #object.id
end
This is right solution?
resources :articles do
delete '/articles/delete_attachment', :to => 'articles#delete_attachment'
put '/articles/edit_attachment', :to => 'articles#edit_attachment'
post '/articles/add_attachment', :to => 'articles#add_attachment'
end
I have no way to check it on the server, because there are still many incompatibilities.
You can change the routes to:
resources :articles do
member do
delete 'delete_attachment'
put 'edit_attachment'
post 'add_attachment'
end
end
If you don't have multiple member routes, you can also pass :on to a route, eliminating the block:
Like,
resources :photos do
get 'preview', on: :member
end
I'm using Ruby and trying to bind an LDAP server. The Ruby documentation seems to be very vague here and it's not obvious what I need to do after the following:
>> require 'uri'
=> true
>> newuri = URI::LDAP.build({:host => '10.1.1.1', :dc => 'cjndemo' , :dc => 'com', :user =>'admin', :password => 'Passw0rd'})
=> #<URI::LDAP:0x007fea9d0cef60 URL:ldap://10.1.1.1?>
What do I need to do to bind then query my LDAP service?
URI::LDAP is only for parsing and generating LDAP URIs. If you want to query the LDAP server you need to use a different tool like net-ldap or ruby-ldap.
An example of binding with simple authentication using net-ldap:
require 'net/ldap'
ldap = Net::LDAP.new(:host => '10.1.1.1',
:auth => {
:method => :simple,
:username => 'cn=admin,dc=cjndemo,dc=com',
:password => 'Passw0rd'
})
if ldap.bind
base = 'dc=cjndemo,dc=com'
filter = Net::LDAP::Filter.eq('objectclass', '*')
ldap.search(:base => base, :filter => filter) do |object|
puts "dn: #{object.dn}"
end
else
# authentication error
end
I'm trying to make a simple email notification when a user signs up.
My user sign up works fine, and I followed the "Sending Email" tutorial exactly but can't get it to work. What am I doing wrong?
user_controller.rb
class Admin::UsersController < InheritedResources::Base
before_filter :admin_only
actions :index, :show, :new, :edit, :create, :update, :destroy
respond_to :html
# def new
# #user = User.new(:invitation_token => params[:invitation_token])
# #user.email = #user.invitation.recipient_email
# end
def create
#user = User.new(params[:user])
UserMailer.deliver_registration_confirmation(#user) < -- where I added the mailer
#user.save(false)
respond_to do |format|
format.html{ redirect_to admin_users_path}
end
end
private
def collection
paginate_options ||= {}
paginate_options[:page] ||= (params[:page] || 1)
paginate_options[:per_page] ||= (params[:per_page] || 20)
#search = User.search(params[:search])
#users ||= #search.all.paginate(paginate_options)
end
end
environments/production.rb
# Settings specified here will take precedence over those in config/environment.rb
config.action_mailer.default_url_options = { :host => 'alpine.totaline.com' }
config.action_mailer.raise_delivery_errors = true
# set delivery method to :smtp, :sendmail or :test
config.action_mailer.delivery_method = :smtp
# these options are only needed if you choose smtp delivery
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 25,
:domain => 'alpine.totaline.com',
:authentication => :login,
:user_name => 'emailname#gmail.com',
:password => 'thepassword'
}
models/user_mailer.rb
class UserMailer < ActionMailer::Base
def registration_confirmation(user)
recipients user.email
from "webmaster#alpinechallenge.com"
subject "Thank you for Registering"
body "You are now registered on the Alpine Challenge!"
end
end
Looks like for Gmail you need to use port 587:
# these options are only needed if you choose smtp delivery
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => '587',
:domain => 'alpine.totaline.com',
:authentication => :login,
:user_name => 'emailname#gmail.com',
:password => 'thepassword'
}
This page contains notes about configuring mail clients for usage with Gmail.