Changesets can be listed by changeset number.
The Git repository is here.
Changeset 113
Numerous changes to use a DRb-based simple authorisation server,
supplied with the Hub application in version 0.1.0 or later (see
Changeset #112). Considerably more reliable than previous cookie
based revisions.
- Comitted by: adh
- Date: Friday October 27 15:49:10 2006 (over 18 years ago)
Affected files:
- rool/rails/gems/hubssolib/trunk/VERSION (diff)
- rool/rails/gems/hubssolib/trunk/hubssolib.gemspec (diff)
- rool/rails/gems/hubssolib/trunk/lib/hub_sso_lib.rb (diff)
rool/rails/gems/hubssolib/trunk/VERSION:
prev. | current | |
1 | ||
1 | 0.1.0 (27-Oct-2006) |
rool/rails/gems/hubssolib/trunk/hubssolib.gemspec:
prev. | current | |
s.platform = Gem::Platform::RUBY | ||
s.name = 'hubssolib' | ||
7 | | |
7 | s.version = '0.1.0' | |
s.author = 'Andrew Hodgkinson and others' | ||
s.email = 'ahodgkin@rowing.org.uk' | ||
s.homepage = 'http://pond.org.uk/ruby/hub/' |
rool/rails/gems/hubssolib/trunk/lib/hub_sso_lib.rb:
prev. | current | |
# split from Hub application. # | ||
####################################################################### | ||
13 | ||
14 | ||
13 | module HubSsoLib | |
16 | ||
17 | ||
18 | ||
19 | ||
15 | require 'drb' | |
21 | ||
22 | ||
17 | # DRb connection | |
18 | HUBSSOLIB_DRB_URI = 'drbunix:/home/adh/rails/fcgi_sockets/hub_drb' | |
24 | ||
25 | ||
20 | # Location of Hub application root. | |
21 | HUB_PATH_PREFIX = '/rails/hub' | |
27 | ||
28 | ||
23 | # Time limit, *in seconds*, for the account inactivity timeout. | |
24 | # If a user performs no Clubhouse actions during this time they | |
25 | # will be automatically logged out upon their next action. | |
26 | HUBSSOLIB_IDLE_TIME_LIMIT = 15 * 60 | |
30 | ||
28 | # Random file location. | |
29 | HUBSSOLIB_RND_FILE_PATH = '/home/adh/.rnd' | |
31 | # Shared cookie name. | |
32 | HUBSSOLIB_COOKIE_NAME = 'hubapp_shared_id' | |
33 | ||
####################################################################### | ||
# Class: Crypto # | ||
# By Hipposoft, 2006 # | ||
... | ... | |
end | ||
end | ||
89 | # Generate a series of pseudo-random bytes of the given length. | |
90 | # | |
91 | def self.random_data(size) | |
92 | data = '' | |
93 | size.times { data << rand(256) } | |
94 | data | |
95 | end | |
96 | ||
97 | def random_data(size) | |
98 | HubSsoLib::Crypto.random_data(size) | |
99 | end | |
100 | ||
101 | # Encode some given data in base-64 format with no line breaks. | |
102 | # | |
103 | def self.pack64(data) | |
104 | [data].pack('m1000000') # Stupid long number to avoid "\n" in the output | |
105 | end | |
106 | ||
107 | def pack64(data) | |
108 | HubSsoLib::Crypto.pack64(data) | |
109 | end | |
110 | ||
111 | # Decode some given data from base-64 format with no line breaks. | |
112 | # | |
113 | def self.unpack64(data) | |
114 | data.unpack('m').first | |
115 | end | |
116 | ||
117 | def unpack64(data) | |
118 | HubSsoLib::Crypto.unpack64(data) | |
119 | end | |
120 | ||
# Encrypt the given data with the AES-256-CBC algorithm using the | ||
# given passphrase. Returns the encrypted result in a string. | ||
# Distantly based upon: | ||
# | ||
# http://www.bigbold.com/snippets/posts/show/576 | ||
# | ||
127 | # In the context of Hub, the passphrase tends to be fixed per IP | |
128 | # address (albeit unknown to the public) and the IV is derived from | |
129 | # it. This means the same data will encode to the same result. With | |
130 | # the source data having some parts which are invariant, security | |
131 | # is compromised. To avoid this, data is prefixed by a quantity of | |
132 | # random bytes, effectively supplementing the IV and ensuring that | |
133 | # different size and content data is generated each time. | |
134 | # | |
def encrypt(data, passphrase) | ||
cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") | ||
cipher.encrypt | ||
... | ... | |
cipher.key = Digest::SHA256.digest(passphrase) | ||
cipher.iv = obtain_iv(passphrase) | ||
142 | rsize = rand(32) | |
143 | data = '' << rsize << random_data(rsize) << data | |
144 | ||
encrypted = cipher.update(data) | ||
encrypted << cipher.final | ||
... | ... | |
decrypted = cipher.update(data) | ||
decrypted << cipher.final | ||
122 | | |
167 | rsize = decrypted[0] | |
168 | return decrypted[rsize + 1..-1] | |
rescue | ||
return nil | ||
end | ||
127 | | |
128 | | |
129 | | |
130 | | |
131 | | |
132 | ||
133 | | |
134 | | |
135 | | |
136 | | |
137 | | |
138 | ||
# Encrypt and base-64 encode the given data with the given passphrase. | ||
# Returns the encoded result. | ||
# | ||
... | ... | |
return nil | ||
end | ||
189 | # Class method that takes an object and passphrase and encrypts | |
190 | # the result. The passphrase is scrambled internally using data | |
191 | # not available to the public, the object serialised (so it must | |
192 | # support serialisation), encrypted and base-64 encoded, and the | |
193 | # 7-bit safe string result returned. On failure, exceptions will | |
194 | # be raised (failure is not expected). | |
195 | # | |
196 | def self.encode_object(object, passphrase) | |
197 | crypto = HubSsoLib::Crypto.new(HUBSSOLIB_RND_FILE_PATH) | |
198 | passphrase = crypto.scramble_passphrase(passphrase) | |
199 | ||
200 | return crypto.encode(Marshal.dump(object), passphrase) | |
201 | end | |
202 | ||
203 | def encode_object(object, passphrase) | |
204 | HubSsoLib::Crypto.encode_object(object, passphrase) | |
205 | end | |
206 | ||
207 | # Class method that takes output from Crypto.encode_object and | |
208 | # decodes it, returning an object reference. Since failure may | |
209 | # result from invalid data input and this can be a common case, | |
210 | # rather than raise an exception as with Crypto.encode_object, | |
211 | # this method returns 'nil' should there be any decode problems. | |
212 | # | |
213 | def self.decode_object(data, passphrase) | |
214 | crypto = HubSsoLib::Crypto.new(HUBSSOLIB_RND_FILE_PATH) | |
215 | passphrase = crypto.scramble_passphrase(passphrase) | |
216 | object = nil | |
217 | ||
218 | if (data && !data.empty?) | |
219 | object = Marshal.load(crypto.decode(data, passphrase)) | |
220 | end | |
221 | ||
222 | return object | |
223 | rescue | |
224 | return nil | |
225 | end | |
226 | ||
227 | def decode_object(data, passphrase) | |
228 | HubSsoLib::Crypto.decode_object(data, passphrase) | |
229 | end | |
230 | ||
# "Scramble" a passphrase. Cookie data encryption is done purely so that | ||
# some hypothetical malicious user cannot easily examine or modify the | ||
# cookie contents for some nefarious purpose. Encryption is done at the | ||
... | ... | |
end # Permissions class | ||
####################################################################### | ||
429 | | |
505 | # Class: User # | |
# By Hipposoft, 2006 # | ||
# # | ||
# Purpose: A representation of the Hub application's User Model in # | ||
... | ... | |
####################################################################### | ||
class User | ||
442 | | |
443 | | |
444 | | |
445 | | |
446 | | |
447 | | |
448 | | |
449 | | |
450 | | |
451 | | |
452 | | |
453 | | |
454 | | |
455 | | |
456 | | |
518 | include DRb::DRbUndumped | |
520 | attr_accessor :user_salt | |
521 | attr_accessor :user_roles | |
522 | attr_accessor :user_updated_at | |
523 | attr_accessor :user_activated_at | |
524 | attr_accessor :user_real_name | |
525 | attr_accessor :user_crypted_password | |
526 | attr_accessor :user_remember_token_expires_at | |
527 | attr_accessor :user_activation_code | |
528 | attr_accessor :user_member_id | |
529 | attr_accessor :user_id | |
530 | attr_accessor :user_password_reset_code | |
531 | attr_accessor :user_remember_token | |
532 | attr_accessor :user_email | |
533 | attr_accessor :user_created_at | |
534 | attr_accessor :user_password_reset_code_expires_at | |
535 | ||
def initialize | ||
459 | | |
460 | | |
461 | | |
462 | | |
463 | | |
464 | | |
465 | | |
466 | | |
467 | | |
468 | | |
469 | | |
470 | | |
471 | | |
472 | | |
473 | | |
537 | @user_salt = nil | |
538 | @user_roles = nil | |
539 | @user_updated_at = nil | |
540 | @user_activated_at = nil | |
541 | @user_real_name = nil | |
542 | @user_crypted_password = nil | |
543 | @user_remember_token_expires_at = nil | |
544 | @user_activation_code = nil | |
545 | @user_member_id = nil | |
546 | @user_id = nil | |
547 | @user_password_reset_code = nil | |
548 | @user_remember_token = nil | |
549 | @user_email = nil | |
550 | @user_created_at = nil | |
551 | @user_password_reset_code_expires_at = nil | |
end | ||
475 | | |
553 | end # User class | |
####################################################################### | ||
478 | | |
556 | # Class: Session # | |
# By Hipposoft, 2006 # | ||
# # | ||
# Purpose: Session support object, used to store session metadata in # | ||
... | ... | |
# History: 22-Oct-2006 (ADH): Created. # | ||
####################################################################### | ||
489 | | |
490 | | |
491 | | |
492 | | |
567 | class Session | |
568 | include DRb::DRbUndumped | |
570 | attr_accessor :session_last_used | |
571 | attr_accessor :session_return_to | |
572 | attr_accessor :session_flash | |
573 | attr_accessor :session_user | |
574 | ||
def initialize | ||
495 | | |
496 | | |
497 | | |
576 | @session_last_used = Time.now.utc | |
577 | @session_return_to = nil | |
578 | @session_flash = {} | |
579 | @session_user = HubSsoLib::User.new | |
end | ||
581 | end # Session class | |
582 | ||
583 | ####################################################################### | |
584 | # Class: SessionFactory # | |
585 | # By Hipposoft, 2006 # | |
586 | # # | |
587 | # Purpose: Build Session objects for DRb server clients. Maintains a # | |
588 | # hash of Session objects. # | |
589 | # # | |
590 | # Author: A.D.Hodgkinson # | |
591 | # # | |
592 | # History: 26-Oct-2006 (ADH): Created. # | |
593 | ####################################################################### | |
594 | ||
595 | class SessionFactory | |
596 | def initialize | |
597 | @sessions = {} | |
598 | end | |
599 | ||
600 | def get_session(key) | |
601 | unless (@sessions.has_key? key) | |
602 | @sessions[key] = HubSsoLib::Session.new | |
603 | end | |
604 | ||
605 | return @sessions[key] | |
606 | end | |
end | ||
####################################################################### | ||
610 | # Module: Server # | |
611 | # By Hipposoft, 2006 # | |
612 | # # | |
613 | # Purpose: DRb server to provide shared data across applications. # | |
614 | # Thanks to RubyPanther, rubyonrails IRC, for suggesting # | |
615 | # this after a cookie-based scheme failed. # | |
616 | # # | |
617 | # Include the module then call hubssolib_launch_server. The # | |
618 | # call will not return as the server runs indefinitely. # | |
619 | # # | |
620 | # Author: A.D.Hodgkinson # | |
621 | # # | |
622 | # History: 26-Oct-2006 (ADH): Created. # | |
623 | ####################################################################### | |
624 | ||
625 | module Server | |
626 | def hubssolib_launch_server | |
627 | DRb.start_service(HUBSSOLIB_DRB_URI, HubSsoLib::SessionFactory.new) | |
628 | DRb.thread.join | |
629 | end | |
630 | end # Server module | |
631 | ||
632 | ####################################################################### | |
# Module: Core # | ||
# Various authors # | ||
# # | ||
505 | | |
506 | | |
507 | | |
508 | | |
636 | # Purpose: The barely recognisable core of acts_as_authenticated's # | |
637 | # AuthenticatedSystem module, modified to work with the # | |
638 | # other parts of HubSsoLib. You should include this module # | |
639 | # to use its facilities. # | |
# # | ||
# Author: Various; adaptation by A.D.Hodgkinson # | ||
# # | ||
... | ... | |
# Preloads @hubssolib_current_user with user data if logged in. | ||
# | ||
def hubssolib_logged_in? | ||
522 | | |
523 | | |
653 | !!self.hubssolib_current_user | |
end | ||
# Check if the user is authorized to perform the current action. If calling | ||
... | ... | |
# Otherwise, ask the permissions object for its opinion. | ||
if (classname.respond_to? :hubssolib_permissions) | ||
540 | | |
670 | return classname.hubssolib_permissions.permitted?(hubssolib_get_user_roles, action) | |
else | ||
return true | ||
end | ||
... | ... | |
return false unless hubssolib_logged_in? | ||
pnormal = HubSsoLib::Roles.new(false).to_s | ||
554 | | |
684 | puser = hubssolib_get_user_roles.to_s | |
return (puser && !puser.empty? && puser != pnormal) | ||
end | ||
... | ... | |
# though Hub certainly does and it gets used internally too. | ||
# | ||
def hubssolib_log_out | ||
563 | | |
564 | | |
565 | | |
693 | # Causes the "hubssolib_current_[foo]=" methods to run, which | |
694 | # deal with everything else. | |
695 | self.hubssolib_current_user = nil | |
696 | self.hubssolib_current_session = nil | |
end | ||
568 | | |
569 | | |
570 | | |
571 | | |
572 | | |
573 | | |
574 | | |
575 | | |
576 | | |
699 | # Accesses the current user, via the DRb server if necessary | |
# | ||
def hubssolib_current_user | ||
579 | | |
702 | hubssolib_get_user_data | |
end | ||
# Store the given user data in the cookie | ||
# | ||
def hubssolib_current_user=(new_user) | ||
585 | | |
586 | | |
587 | | |
588 | | |
589 | | |
590 | ||
591 | | |
hubssolib_set_user_data(new_user) | ||
end | ||
... | ... | |
# session object if need be. | ||
# | ||
def hubssolib_current_session | ||
599 | | |
715 | @hubssolib_current_session ||= hubssolib_get_session_data | |
end | ||
602 | | |
718 | # Store the given session data. | |
# | ||
def hubssolib_current_session=(new_session) | ||
@hubssolib_current_session = new_session | ||
606 | | |
end | ||
724 | # Public read-only accessor methods for common user activities: | |
725 | # return the current user's roles as a Roles object, or nil if | |
726 | # there's no user. | |
727 | # | |
728 | def hubssolib_get_user_roles | |
729 | user = self.hubssolib_current_user | |
730 | user ? user.user_roles.to_authenticated_roles : nil | |
731 | end | |
732 | ||
733 | # Public read-only accessor methods for common user activities: | |
734 | # return the current user's name as a string, or nil if there's | |
735 | # no user. See also hubssolib_unique_name. | |
736 | # | |
737 | def hubssolib_get_user_name | |
738 | user = self.hubssolib_current_user | |
739 | user ? user.user_real_name : nil | |
740 | end | |
741 | ||
# Return a human-readable unique ID for a user. We don't want to | ||
# have e-mail addresses all over the place, but don't want to rely | ||
# on real names as unique - they aren't. Instead, produce a | ||
# composite of the user's account database ID (which must be | ||
613 | | |
746 | # unique by definition) and their real name. See also | |
747 | # hubssolib_get_name. | |
# | ||
def hubssolib_unique_name | ||
user = hubssolib_current_user | ||
617 | | |
751 | user ? "#{user.user_real_name} (#{user.user_id})" : 'Anonymous' | |
end | ||
# Main filter method to implement HubSsoLib permissions management, | ||
621 | | |
755 | # session expiry and so-on. Call from controllers only, always as a | |
756 | # before_fitler. | |
# | ||
623 | | |
758 | def hubssolib_beforehand | |
# Does this action require a logged in user? | ||
... | ... | |
end | ||
end | ||
691 | | |
826 | # Main after_filter method to tidy up after running state changes. | |
# | ||
828 | def hubssolib_afterwards | |
829 | # Nothing to do right now; maybe in future... | |
830 | end | |
831 | ||
832 | # Store the URI of the current request in the session, or store the | |
833 | # optional supplied specific URI. | |
834 | # | |
# We can return to this location by calling #redirect_back_or_default. | ||
694 | | |
695 | | |
836 | # | |
837 | def hubssolib_store_location(uri_str = request.request_uri) | |
838 | ||
839 | if (uri_str && !uri_str.empty?) | |
840 | uri_str = hubssolib_promote_uri_to_ssl(uri_str, request.host) | |
841 | hubssolib_set_return_to(uri_str) | |
842 | else | |
843 | hubssolib_set_return_to(nil) | |
844 | end | |
845 | ||
end | ||
# Redirect to the URI stored by the most recent store_location call or | ||
# to the passed default. | ||
def hubssolib_redirect_back_or_default(default) | ||
url = hubssolib_get_return_to | ||
852 | hubssolib_set_return_to(nil) | |
url ? redirect_to_url(url) : redirect_to(default) | ||
704 | | |
end | ||
857 | # Take a URI and pass an optional host parameter. Decomposes the URI, | |
858 | # sets the host you provide (or leaves it alone if you omit the | |
859 | # parameter), then forces the scheme to 'https'. Returns the result | |
860 | # as a flat string. | |
861 | ||
862 | def hubssolib_promote_uri_to_ssl(uri_str, host = nil) | |
863 | uri = URI.parse(uri_str) | |
864 | uri.host = host if host | |
865 | uri.scheme = 'https' | |
866 | return uri.to_s | |
867 | end | |
868 | ||
# Ensure the current request is carried out over HTTPS by redirecting | ||
708 | | |
870 | # back to the current URL with the HTTPS protocol if it isn't. Returns | |
871 | # 'true' if not redirected (already HTTPS), else 'false'. | |
# | ||
def hubssolib_ensure_https | ||
711 | | |
874 | unless request.ssl? | |
875 | # This isn't reliable: redirect_to({ :protocol => 'https://' }) | |
876 | redirect_to (hubssolib_promote_uri_to_ssl(request.request_uri, request.host)) | |
877 | return false | |
878 | else | |
879 | return true | |
880 | end | |
end | ||
# Public methods to set some data that would normally go in @session, | ||
... | ... | |
# private methods for things like session expiry too. | ||
# | ||
def hubssolib_get_flash() | ||
720 | | |
889 | f = self.hubssolib_current_session ? self.hubssolib_current_session.session_flash : nil | |
890 | return f || {} | |
end | ||
def hubssolib_set_flash(symbol, message) | ||
894 | return unless self.hubssolib_current_session | |
f = hubssolib_get_flash | ||
f[symbol] = message | ||
726 | | |
897 | self.hubssolib_current_session.session_flash = f | |
end | ||
def hubssolib_clear_flash | ||
730 | | |
901 | return unless self.hubssolib_current_session | |
902 | self.hubssolib_current_session.session_flash = {} | |
end | ||
# Helper methods to output flash data. It isn't merged into the standard | ||
... | ... | |
# result in the flash hash now it has been used. | ||
# | ||
def hubssolib_flash_tag(key) | ||
741 | | |
913 | value = hubssolib_get_flash[key] | |
if (value) | ||
hubssolib_set_flash(key, nil) | ||
... | ... | |
end | ||
end | ||
751 | | |
923 | # Next, return tags for a standard application flash using the given key. | |
# | ||
def hubssolib_standard_flash_tag(key) | ||
754 | | |
926 | value = flash[key] if defined?(flash) | |
if (value) | ||
flash.delete(key) | ||
... | ... | |
# These known key values are used to guarantee an order in the output | ||
# for cases where multiple messages are defined. | ||
771 | | |
772 | | |
773 | | |
943 | tags = hubssolib_flash_tag(:notice) << | |
944 | hubssolib_flash_tag(:attention) << | |
945 | hubssolib_flash_tag(:alert) | |
tags << hubssolib_standard_flash_tag(:notice) << | ||
hubssolib_standard_flash_tag(:attention) << | ||
... | ... | |
# Now pick up anything else. | ||
hubssolib_get_flash.each do |key, value| | ||
782 | | |
954 | tags << hubssolib_flash_tag(key) if (value and !value.empty?) | |
end | ||
flash.each do |key, value| | ||
786 | | |
787 | | |
958 | tags << hubssolib_standard_flash_tag(key) if (value and !value.empty?) | |
959 | end if defined?(flash) | |
return tags | ||
end | ||
964 | # Retrieve the message of an exception stored as an object in the given | |
965 | # string. | |
966 | # | |
967 | def hubssolib_get_exception_message(id_data) | |
968 | hubssolib_get_exception_data(id_data) | |
969 | end | |
970 | ||
# Inclusion hook to make various methods available as ActionView | ||
# helper methods. | ||
973 | # | |
def self.included(base) | ||
base.send :helper_method, | ||
:hubssolib_current_user, | ||
977 | :hubssolib_unique_name, | |
:hubssolib_logged_in?, | ||
:hubssolib_authorized?, | ||
:hubssolib_privileged?, | ||
:hubssolib_flash_tags | ||
982 | rescue | |
983 | # We're not always included in controllers... | |
984 | nil | |
end | ||
private | ||
... | ... | |
# halted (since the overall return value is therefore 'false'). | ||
# | ||
def hubssolib_must_login | ||
811 | | |
812 | | |
995 | # If HTTP, redirect to the same place, but HTTPS. Then we can store the | |
996 | # flash and return-to in the session data. We'll have the same set of | |
997 | # before-filter operations running and they'll find out we're either | |
998 | # authorised after all, or come back to this very function, which will | |
999 | # now be happily running from an HTTPS connection and will go on to set | |
1000 | # the flash and redirect to the login page. | |
1001 | ||
1002 | if hubssolib_ensure_https | |
1003 | hubssolib_set_flash(:alert, 'You must log in before you can continue.') | |
1004 | redirect_to HUB_PATH_PREFIX + '/account/login' | |
1005 | end | |
1006 | ||
return false | ||
end | ||
... | ... | |
# halted (since the overall return value is therefore 'false'). | ||
# | ||
def hubssolib_access_denied | ||
822 | | |
823 | | |
1016 | # See hubsso_must_login for the reason behind the following call. | |
1017 | ||
1018 | if hubssolib_ensure_https | |
1019 | hubssolib_set_flash(:alert, 'You do not have permission to carry out that action on this site.') | |
1020 | redirect_to HUB_PATH_PREFIX + '/' | |
1021 | end | |
1022 | ||
return false | ||
end | ||
... | ... | |
# Retrieve data from a given cookie with encrypted contents. | ||
# | ||
857 | | |
858 | | |
859 | | |
860 | | |
861 | | |
862 | ||
863 | | |
864 | | |
865 | | |
866 | ||
867 | | |
868 | | |
869 | | |
1056 | def hubssolib_get_secure_cookie_data(name) | |
1057 | return HubSsoLib::Crypto.decode_object(cookies[name], request.remote_ip) | |
end | ||
# Set the given cookie to a value of the given data, which | ||
# will be encrypted. | ||
# | ||
875 | | |
876 | | |
877 | | |
878 | | |
879 | | |
880 | | |
881 | | |
882 | | |
883 | | |
1063 | def hubssolib_set_secure_cookie_data(name, value) | |
1064 | if (@hubssolib_have_written_cookie) | |
1065 | raise "HubSsoLib: Attmept to set cookie '#{name}' more than once" | |
end | ||
1068 | @hubssolib_have_written_cookie = true | |
1069 | ||
1070 | # Using cookies.delete *should* work but doesn't. Set the | |
1071 | # cookie with nil data instead. | |
1072 | ||
1073 | data = value.nil? ? nil : HubSsoLib::Crypto.encode_object(value, request.remote_ip) | |
1074 | ||
# No expiry time; to aid security, use session cookies only. | ||
cookies[name] = { | ||
... | ... | |
} | ||
end | ||
895 | | |
1084 | # Retrieve user data from the DRb server. | |
# | ||
def hubssolib_get_user_data | ||
898 | | |
1087 | user = self.hubssolib_current_session ? self.hubssolib_current_session.session_user : nil | |
1088 | ||
1089 | if (user && user.user_id) | |
1090 | return user | |
1091 | else | |
1092 | return nil | |
1093 | end | |
end | ||
901 | | |
902 | | |
903 | | |
def hubssolib_set_user_data(user) | ||
905 | | |
1097 | self.hubssolib_current_session.session_user = user | |
end | ||
908 | | |
909 | | |
def hubssolib_get_session_data | ||
911 | | |
1101 | ||
1102 | # If we're not using SSL, forget it | |
1103 | return nil unless request.ssl? | |
1104 | ||
1105 | # If we've no cookie, we need a new session ID | |
1106 | key = hubssolib_get_secure_cookie_data(HUBSSOLIB_COOKIE_NAME) | |
1107 | ||
1108 | unless (key) | |
1109 | key = HubSsoLib::Crypto.pack64(HubSsoLib::Crypto.random_data(48)) | |
1110 | hubssolib_set_secure_cookie_data(HUBSSOLIB_COOKIE_NAME, key) | |
1111 | end | |
1112 | ||
1113 | DRb.start_service() | |
1114 | ||
1115 | factory = DRbObject.new_with_uri(HUBSSOLIB_DRB_URI) | |
1116 | return factory.get_session(key) | |
1117 | ||
1118 | rescue Exception => e | |
1119 | ||
1120 | # At this point there tends to be no Session data, so we're | |
1121 | # going to have to encode the exception data into the URI... | |
1122 | ||
1123 | suffix = '/' + CGI::escape(hubssolib_set_exception_data(e)) | |
1124 | new_path = HUB_PATH_PREFIX + '/tasks/service' | |
1125 | redirect_to new_path + suffix unless request.path.include?(new_path) | |
1126 | return nil | |
end | ||
914 | | |
915 | | |
916 | | |
917 | | |
918 | | |
1129 | def hubssolib_set_session_data(session) | |
1130 | # Nothing to do presently - DRb handles everything | |
end | ||
921 | | |
1133 | # Encode exception data into a string suitable for using in a URL | |
1134 | # if CGI escaped first. Pass the exception object; stores only the | |
1135 | # message. | |
# | ||
923 | | |
924 | | |
925 | | |
926 | | |
927 | | |
1137 | def hubssolib_set_exception_data(e) | |
1138 | HubSsoLib::Crypto.encode_object(e.message, request.remote_ip) | |
end | ||
930 | | |
931 | | |
1141 | # Decode exception data encoded with hubssolib_set_exception_data. | |
1142 | # Returns the originally stored message string or 'nil' if there | |
1143 | # are any decoding problems. Pass the encoded data. | |
# | ||
933 | | |
934 | | |
935 | | |
936 | | |
937 | ||
938 | | |
939 | | |
940 | | |
1145 | def hubssolib_get_exception_data(data) | |
1146 | HubSsoLib::Crypto.decode_object(data, request.remote_ip) | |
end | ||
943 | | |
1149 | # Various accessors that ultimately run through the DRb server if | |
1150 | # the session data is available, else return default values. | |
def hubssolib_get_last_used | ||
946 | | |
1153 | session = self.hubssolib_current_session | |
1154 | session ? session.session_last_used : Time.now.utc | |
end | ||
def hubssolib_set_last_used(time) | ||
950 | | |
1158 | return unless self.hubssolib_current_session | |
1159 | self.hubssolib_current_session.session_last_used = time | |
end | ||
def hubssolib_get_return_to | ||
954 | | |
1163 | session = self.hubssolib_current_session | |
1164 | session ? session.session_return_to : nil | |
end | ||
957 | | |
958 | | |
1167 | def hubssolib_set_return_to(uri) | |
1168 | return unless self.hubssolib_current_session | |
1169 | self.hubssolib_current_session.session_return_to = uri | |
end | ||
end # Core module |