Init backend of generic external credentials.
This commit is contained in:
parent
9a702b528c
commit
23bb04566d
9 changed files with 183 additions and 151 deletions
1
Gemfile
1
Gemfile
|
@ -33,7 +33,6 @@ gem 'omniauth-linkedin'
|
|||
gem 'omniauth-google-oauth2'
|
||||
|
||||
gem 'twitter'
|
||||
gem 'twitter_oauth'
|
||||
gem 'koala'
|
||||
gem 'mail', '~> 2.5.0'
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ GEM
|
|||
simplecov-rcov (0.2.3)
|
||||
simplecov (>= 0.4.1)
|
||||
slop (3.6.0)
|
||||
spring (1.5.0)
|
||||
spring (1.6.0)
|
||||
sprockets (3.5.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
|
@ -307,10 +307,6 @@ GEM
|
|||
memoizable (~> 0.4.0)
|
||||
naught (~> 1.0)
|
||||
simple_oauth (~> 0.3.0)
|
||||
twitter_oauth (0.4.94)
|
||||
json (>= 1.8.0)
|
||||
mime-types (>= 1.16)
|
||||
oauth (>= 0.4.7)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (2.7.2)
|
||||
|
@ -373,7 +369,6 @@ DEPENDENCIES
|
|||
test-unit
|
||||
therubyracer
|
||||
twitter
|
||||
twitter_oauth
|
||||
uglifier
|
||||
writeexcel
|
||||
|
||||
|
|
75
app/controllers/external_credentials_controller.rb
Normal file
75
app/controllers/external_credentials_controller.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class ExternalCredentialsController < ApplicationController
|
||||
before_action :authentication_check
|
||||
|
||||
def index
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
model_index_render(ExternalCredential, params)
|
||||
end
|
||||
|
||||
def show
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
model_show_render(ExternalCredential, params)
|
||||
end
|
||||
|
||||
def create
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
|
||||
# try access
|
||||
begin
|
||||
attributes = ExternalCredential.app_verify(params)
|
||||
model_create_render(ExternalCredential, { name: params[:provider].downcase, credentials: attributes })
|
||||
return
|
||||
rescue => e
|
||||
render json: { error: e.message }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
|
||||
# try access
|
||||
begin
|
||||
attributes = ExternalCredential.app_verify(params)
|
||||
model_update_render(ExternalCredential, { name: params[:provider].downcase, credentials: attributes })
|
||||
return
|
||||
rescue => e
|
||||
render json: { error: e.message }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
model_destory_render(ExternalCredential, params)
|
||||
end
|
||||
|
||||
def link_account
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
provider = params[:provider].downcase
|
||||
|
||||
attributes = ExternalCredential.request_account_to_link(provider, callback_url(provider))
|
||||
|
||||
session[:request_token] = attributes[:request_token]
|
||||
|
||||
redirect_to attributes[:authorize_url]
|
||||
end
|
||||
|
||||
def callback
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
provider = params[:provider].downcase
|
||||
|
||||
channel = ExternalCredential.link_account(provider, session[:request_token], params)
|
||||
|
||||
session[:request_token] = nil
|
||||
|
||||
render json: channel
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def callback_url(provider)
|
||||
"#{Setting.get('http_type')}://#{Setting.get('fqdn')}#{Rails.configuration.api_path}/external_credentials/#{provider}/callback"
|
||||
end
|
||||
|
||||
end
|
|
@ -1,129 +0,0 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
require 'twitter_oauth'
|
||||
|
||||
class ExternalCredentialsTwitterController < ApplicationController
|
||||
before_action :authentication_check
|
||||
|
||||
def index
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
|
||||
twitter_credential = ExternalCredential.find_by(name: 'Twitter')
|
||||
|
||||
# TODO: refactor
|
||||
result = {
|
||||
# consumer_key: nil,
|
||||
# consumer_secret: nil,
|
||||
}
|
||||
if !twitter_credential.nil?
|
||||
|
||||
# p twitter_credential.credentials.inspect
|
||||
|
||||
result[:consumer_key] = twitter_credential.credentials[:consumer_key]
|
||||
result[:consumer_secret] = twitter_credential.credentials[:consumer_secret]
|
||||
result[:authorize_url] = twitter_credential.credentials[:authorize_url]
|
||||
end
|
||||
|
||||
render json: result, status: :ok
|
||||
end
|
||||
|
||||
def show
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
model_show_render(ExternalCredential, params)
|
||||
end
|
||||
|
||||
def create
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
|
||||
credentials = handle_credentials(params)
|
||||
|
||||
# create object
|
||||
twitter_credential = ExternalCredential.new( name: 'Twitter', credentials: credentials )
|
||||
|
||||
# save object
|
||||
twitter_credential.save!
|
||||
|
||||
redirect_to credentials[:authorize_url]
|
||||
end
|
||||
|
||||
def update
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
|
||||
credentials = handle_credentials(params)
|
||||
|
||||
# find object
|
||||
twitter_credential = ExternalCredential.find(params[:id])
|
||||
|
||||
# update object
|
||||
twitter_credential.update_attributes!( name: 'Twitter', credentials: credentials )
|
||||
|
||||
redirect_to credentials.authorize_url
|
||||
end
|
||||
|
||||
def destroy
|
||||
return if deny_if_not_role(Z_ROLENAME_ADMIN)
|
||||
model_destory_render(ExternalCredential, params)
|
||||
end
|
||||
|
||||
def auth
|
||||
# https://zammad.tld/twitter_auth?oauth_token=uP15WgAAAAAAivjgAAABUSUkP5Y&oauth_verifier=OlKro1xj7gBQ5cwdvlcYQEniiEm1THsd
|
||||
params[:oauth_token]
|
||||
params[:oauth_verifier]
|
||||
|
||||
params.require(:name, :oauth_token, :oauth_verifier)
|
||||
params.permit(:name, :oauth_token, :oauth_verifier)
|
||||
|
||||
twitter_credential = ExternalCredential.find_by( name: 'Twitter' )
|
||||
|
||||
if ( twitter_credential[:credentials][:oauth_token] != params[:oauth_token] )
|
||||
# TODO: ERROR
|
||||
end
|
||||
|
||||
access_token = client.authorize(
|
||||
twitter_credential[:credentials][:oauth_token],
|
||||
twitter_credential[:credentials][:oauth_token_secret],
|
||||
oauth_verifier: params[:oauth_verifier]
|
||||
)
|
||||
|
||||
credentials = {
|
||||
consumer_key: twitter_credential[:credentials][:consumer_key],
|
||||
consumer_secret: twitter_credential[:credentials][:consumer_secret],
|
||||
access_token: access_token.token,
|
||||
access_token_secret: access_token.secret,
|
||||
}
|
||||
|
||||
twitter_credential.update_attributes!(credentials: credentials )
|
||||
|
||||
# TODO
|
||||
redirect_to "#{Setting.get('http_type')}://#{Setting.get('fqdn')}/#admin/path/external_credentials_twitter"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_credentials(params)
|
||||
|
||||
params.require(:consumer_key)
|
||||
params.require(:consumer_secret)
|
||||
|
||||
params.permit(:consumer_key, :consumer_secret)
|
||||
|
||||
credentials = {
|
||||
consumer_key: params[:consumer_key],
|
||||
consumer_secret: params[:consumer_secret],
|
||||
}
|
||||
|
||||
client = TwitterOAuth::Client.new(
|
||||
consumer_key: credentials[:consumer_key],
|
||||
consumer_secret: credentials[:consumer_secret],
|
||||
)
|
||||
|
||||
# TODO: improve callback URL
|
||||
request_token = client.request_token(oauth_callback: "#{Setting.get('http_type')}://#{Setting.get('fqdn')}/#{Rails.configuration.api_path}/external_credentials_twitter/Twitter/auth")
|
||||
|
||||
credentials[:oauth_token] = request_token.token
|
||||
credentials[:oauth_token_secret] = request_token.secret
|
||||
credentials[:authorize_url] = request_token.authorize_url
|
||||
|
||||
credentials
|
||||
end
|
||||
end
|
|
@ -1,4 +1,28 @@
|
|||
class ExternalCredential < ActiveRecord::Base
|
||||
class ExternalCredential < ApplicationModel
|
||||
include ApplicationLib
|
||||
|
||||
validates :name, presence: true
|
||||
store :credentials
|
||||
|
||||
def self.app_verify(params)
|
||||
backend = load_backend(params[:provider])
|
||||
backend.app_verify(params)
|
||||
end
|
||||
|
||||
def self.request_account_to_link(provider, callback)
|
||||
backend = load_backend(provider)
|
||||
backend.request_account_to_link(callback)
|
||||
end
|
||||
|
||||
def self.link_account(provider, request_token, params)
|
||||
backend = load_backend(provider)
|
||||
backend.link_account(request_token, params)
|
||||
end
|
||||
|
||||
def self.load_backend(provider)
|
||||
adapter = "ExternalCredential::#{provider.camelcase}"
|
||||
require "#{adapter.to_filename}"
|
||||
load_adapter(adapter)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
15
config/routes/external_credentials.rb
Normal file
15
config/routes/external_credentials.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
Zammad::Application.routes.draw do
|
||||
api_path = Rails.configuration.api_path
|
||||
|
||||
# CRUD
|
||||
match api_path + '/external_credentials', to: 'external_credentials#index', via: :get
|
||||
match api_path + '/external_credentials/:id', to: 'external_credentials#show', via: :get
|
||||
match api_path + '/external_credentials', to: 'external_credentials#create', via: :post
|
||||
match api_path + '/external_credentials/:id', to: 'external_credentials#update', via: :put
|
||||
match api_path + '/external_credentials/:id', to: 'external_credentials#destroy', via: :delete
|
||||
|
||||
# callback URL
|
||||
match api_path + '/external_credentials/:provider/link_account', to: 'external_credentials#link_account', via: :get
|
||||
match api_path + '/external_credentials/:provider/callback', to: 'external_credentials#callback', via: :get
|
||||
|
||||
end
|
|
@ -1,14 +0,0 @@
|
|||
Zammad::Application.routes.draw do
|
||||
api_path = Rails.configuration.api_path
|
||||
|
||||
# CRUD
|
||||
match api_path + '/external_credentials_twitter', to: 'external_credentials_twitter#index', via: :get
|
||||
match api_path + '/external_credentials_twitter/:id', to: 'external_credentials_twitter#show', via: :get
|
||||
match api_path + '/external_credentials_twitter', to: 'external_credentials_twitter#create', via: :post
|
||||
match api_path + '/external_credentials_twitter/:id', to: 'external_credentials_twitter#update', via: :put
|
||||
match api_path + '/external_credentials_twitter/:id', to: 'external_credentials_twitter#destroy', via: :delete
|
||||
|
||||
# callback URL
|
||||
match api_path + '/external_credentials_twitter/:name/auth', to: 'external_credentials_twitter#auth', via: :get
|
||||
|
||||
end
|
|
@ -128,6 +128,7 @@ returns
|
|||
'Channels' => 'Channel',
|
||||
'EmailAddresses' => 'EmailAddress',
|
||||
'Signatures' => 'Signature',
|
||||
'Groups' => 'Group',
|
||||
}
|
||||
model_map.each {|map_name, model|
|
||||
next if !auto_wizard_hash[map_name]
|
||||
|
|
66
lib/external_credential/twitter.rb
Normal file
66
lib/external_credential/twitter.rb
Normal file
|
@ -0,0 +1,66 @@
|
|||
class ExternalCredential::Twitter
|
||||
|
||||
def self.app_verify(params)
|
||||
attributes = {
|
||||
consumer_key: params[:consumer_key],
|
||||
consumer_secret: params[:consumer_secret],
|
||||
}
|
||||
request_account_to_link('', attributes)
|
||||
attributes
|
||||
end
|
||||
|
||||
def self.request_account_to_link(callback_url, credentials = {})
|
||||
external_credential = ExternalCredential.find_by(name: 'twitter')
|
||||
consumer = OAuth::Consumer.new(
|
||||
credentials[:consumer_key] || external_credential.credentials[:consumer_key],
|
||||
credentials[:consumer_secret] || external_credential.credentials[:consumer_secret], {
|
||||
site: 'https://api.twitter.com'
|
||||
})
|
||||
request_token = consumer.get_request_token(oauth_callback: callback_url)
|
||||
{
|
||||
request_token: request_token,
|
||||
authorize_url: request_token.authorize_url,
|
||||
}
|
||||
end
|
||||
|
||||
def self.link_account(request_token, params)
|
||||
fail if request_token.params[:oauth_token] != params[:oauth_token]
|
||||
|
||||
external_credential = ExternalCredential.find_by(name: 'twitter')
|
||||
access_token = request_token.get_access_token(oauth_verifier: params[:oauth_verifier])
|
||||
client = Twitter::REST::Client.new(
|
||||
consumer_key: external_credential.credentials[:consumer_key],
|
||||
consumer_secret: external_credential.credentials[:consumer_secret],
|
||||
access_token: access_token.token,
|
||||
access_token_secret: access_token.secret,
|
||||
)
|
||||
user = client.user
|
||||
|
||||
# create channel
|
||||
Channel.create(
|
||||
area: 'Twitter::Account',
|
||||
options: {
|
||||
adapter: 'twitter',
|
||||
user: {
|
||||
id: user.id,
|
||||
screen_name: user.screen_name,
|
||||
},
|
||||
auth: {
|
||||
external_credential_id: external_credential.id,
|
||||
oauth_token: access_token.token,
|
||||
oauth_token_secret: access_token.secret,
|
||||
},
|
||||
sync: {
|
||||
search: [],
|
||||
mentions: {},
|
||||
direct_messages: {}
|
||||
}
|
||||
},
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue