mirror of
https://github.com/postgres/pgweb.git
synced 2025-08-10 00:42:06 +00:00
Add redmine community auth plugin
Written by Alex Shulgin (ash at commandprompt.com)
This commit is contained in:
3
tools/communityauth/sample/ruby/README.rdoc
Normal file
3
tools/communityauth/sample/ruby/README.rdoc
Normal file
@ -0,0 +1,3 @@
|
||||
= pgcommunityauth
|
||||
|
||||
Description goes here
|
@ -0,0 +1,3 @@
|
||||
<p>
|
||||
PostgreSQL community auth login page.
|
||||
</p>
|
@ -0,0 +1,12 @@
|
||||
<p>
|
||||
<%= label_tag :settings_authsite_id, "Auth site ID" %>
|
||||
<%= text_field_tag 'settings[authsite_id]', settings['authsite_id'], :size => 5 %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :settings_cipher_key, "Cipher key (Base64)" %>
|
||||
<%= text_field_tag 'settings[cipher_key]', settings['cipher_key'] %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :settings_default_url, "Default URL (/)" %>
|
||||
<%= text_field_tag 'settings[default_url]', settings['default_url'] %>
|
||||
</p>
|
3
tools/communityauth/sample/ruby/config/locales/en.yml
Normal file
3
tools/communityauth/sample/ruby/config/locales/en.yml
Normal file
@ -0,0 +1,3 @@
|
||||
# English strings go here for Rails i18n
|
||||
en:
|
||||
my_label: "My label"
|
3
tools/communityauth/sample/ruby/config/routes.rb
Normal file
3
tools/communityauth/sample/ruby/config/routes.rb
Normal file
@ -0,0 +1,3 @@
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.pgcommunityauth '/pgcommunityauth', :controller => 'account', :action => 'pgcommunityauth'
|
||||
end
|
17
tools/communityauth/sample/ruby/init.rb
Normal file
17
tools/communityauth/sample/ruby/init.rb
Normal file
@ -0,0 +1,17 @@
|
||||
require 'redmine'
|
||||
require 'dispatcher'
|
||||
|
||||
Dispatcher.to_prepare do
|
||||
require_dependency 'account_controller'
|
||||
|
||||
AccountController.send(:include, RedminePgcommunityauth::AccountControllerPatch)
|
||||
end
|
||||
|
||||
Redmine::Plugin.register :redmine_pgcommunityauth do
|
||||
name 'Redmine Pgcommunityauth plugin'
|
||||
author 'Alex Shulgin <ash@commandprompt.com>'
|
||||
description ''
|
||||
version '0.0.1'
|
||||
|
||||
settings :default => {}, :partial => 'settings/redmine_pgcommunityauth_settings'
|
||||
end
|
2
tools/communityauth/sample/ruby/lang/en.yml
Normal file
2
tools/communityauth/sample/ruby/lang/en.yml
Normal file
@ -0,0 +1,2 @@
|
||||
# English strings go here
|
||||
my_label: "My label"
|
@ -0,0 +1,104 @@
|
||||
require 'base64'
|
||||
require 'openssl' # aes gem doesn't let us disable PKCS#5 padding
|
||||
|
||||
module RedminePgcommunityauth
|
||||
module AccountControllerPatch
|
||||
unloadable
|
||||
|
||||
class AuthTokenExpiredError < RuntimeError; end
|
||||
class InvalidAuthTokenError < RuntimeError; end
|
||||
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
alias_method_chain :login, :pgcommunityauth
|
||||
alias_method_chain :logout, :pgcommunityauth
|
||||
end
|
||||
end
|
||||
|
||||
def login_with_pgcommunityauth
|
||||
redirect_to pgcommunityauth_login_url
|
||||
end
|
||||
|
||||
def logout_with_pgcommunityauth
|
||||
logout_user
|
||||
redirect_to pgcommunityauth_logout_url
|
||||
end
|
||||
|
||||
# GET /pgcommunityauth
|
||||
def pgcommunityauth
|
||||
if params[:s] == 'logout'
|
||||
flash[:notice] = "Successfully logged out from PG community sites."
|
||||
return
|
||||
end
|
||||
|
||||
data = (params[:d] || "").tr('-_', '+/')
|
||||
iv = (params[:i] || "").tr('-_', '+/')
|
||||
|
||||
qs = aes_decrypt(data, iv).rstrip
|
||||
auth = Rack::Utils.parse_query(qs)
|
||||
|
||||
# check auth hash for mandatory keys
|
||||
raise InvalidAuthTokenError.new unless %w(t u f l e).all?{ |x| auth.keys.include?(x) }
|
||||
|
||||
# check auth token timestamp: issued 10 seconds ago or less
|
||||
raise AuthTokenExpiredError.new unless Time.now.to_i <= auth['t'].to_i + 10
|
||||
|
||||
# prepare attrs for create or update
|
||||
attrs = {
|
||||
:firstname => auth['f'],
|
||||
:lastname => auth['l'],
|
||||
:mail => auth['e']
|
||||
}
|
||||
if user = User.find_by_login(auth['u'])
|
||||
user.update_attributes! attrs
|
||||
else
|
||||
user = User.new(attrs)
|
||||
# can't pass protected attr in new/create
|
||||
user.login = auth['u']
|
||||
user.save!
|
||||
end
|
||||
|
||||
params[:back_url] = auth['su'] || pgcommunityauth_settings[:default_url]
|
||||
successful_authentication(user)
|
||||
rescue OpenSSL::Cipher::CipherError
|
||||
flash[:error] = "Invalid PG communityauth message received."
|
||||
rescue InvalidAuthTokenError
|
||||
flash[:error] = "Invalid PG communityauth token received."
|
||||
rescue AuthTokenExpiredError
|
||||
flash[:error] = "PG community auth token expired."
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pgcommunityauth_settings
|
||||
Setting['plugin_redmine_pgcommunityauth']
|
||||
end
|
||||
|
||||
def pgcommunityauth_base_url
|
||||
"https://www.postgresql.org/account/auth/#{pgcommunityauth_settings[:authsite_id]}"
|
||||
end
|
||||
|
||||
def pgcommunityauth_login_url
|
||||
"#{pgcommunityauth_base_url}/"
|
||||
end
|
||||
|
||||
def pgcommunityauth_logout_url
|
||||
"#{pgcommunityauth_base_url}/logout/"
|
||||
end
|
||||
|
||||
def aes_decrypt(data, iv)
|
||||
key = Base64.decode64(pgcommunityauth_settings[:cipher_key])
|
||||
|
||||
cipher = OpenSSL::Cipher.new("AES-#{key.size*8}-CBC")
|
||||
cipher.decrypt
|
||||
|
||||
# this is the key point here, otherwise we could use
|
||||
# AES.decrypt()
|
||||
cipher.padding = 0
|
||||
|
||||
cipher.key = key
|
||||
cipher.iv = Base64.decode64(iv)
|
||||
cipher.update(Base64.decode64(data)) + cipher.final
|
||||
end
|
||||
end
|
||||
end
|
5
tools/communityauth/sample/ruby/test/test_helper.rb
Normal file
5
tools/communityauth/sample/ruby/test/test_helper.rb
Normal file
@ -0,0 +1,5 @@
|
||||
# Load the normal Rails helper
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
|
||||
|
||||
# Ensure that we are using the temporary fixture path
|
||||
Engines::Testing.set_fixture_path
|
Reference in New Issue
Block a user