Changesets can be listed by changeset number.
The Git repository is here.
Changeset 107
Further updates to the HubSsoLib Gem to support cross-application,
same domain single sign-on.
- Comitted by: adh
- Date: Monday October 23 18:12:59 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.0.4 (23-Oct-2006) |
rool/rails/gems/hubssolib/trunk/hubssolib.gemspec:
prev. | current | |
s.platform = Gem::Platform::RUBY | ||
s.name = 'hubssolib' | ||
7 | | |
7 | s.version = '0.0.4' | |
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 | # Location of Hub application root. | |
14 | HUB_PATH_PREFIX = '/rails/hub' | |
15 | ||
16 | # Time limit, *in seconds*, for the account inactivity timeout. | |
17 | # If a user performs no Clubhouse actions during this time they | |
18 | # will be automatically logged out upon their next action. | |
19 | HUBSSOLIB_IDLE_TIME_LIMIT = 15 * 60 | |
20 | ||
21 | # Random file location. | |
22 | HUBSSOLIB_RND_FILE_PATH = '/home/adh/.rnd' | |
23 | ||
24 | # Session data cookie name. | |
25 | HUBSSOLIB_SESSION_DATA_KEY = 'hubapp_session_data' | |
26 | ||
27 | # Session support cookie name. | |
28 | HUBSSOLIB_SESSION_SUPPORT_KEY = 'hubapp_session_support' | |
29 | ||
module HubSsoLib | ||
####################################################################### | ||
... | ... | |
return nil | ||
end | ||
127 | # Encode some given data in base-64 format with no line breaks. | |
128 | # | |
129 | def pack64(data) | |
130 | [data].pack('m1000000') # Stupid long number to avoid "\n" in the output | |
131 | end | |
132 | ||
133 | # Decode some given data from base-64 format with no line breaks. | |
134 | # | |
135 | def unpack64(data) | |
136 | data.unpack('m').first | |
137 | end | |
138 | ||
# Encrypt and base-64 encode the given data with the given passphrase. | ||
# Returns the encoded result. | ||
# | ||
def encode(data, passphrase) | ||
114 | | |
143 | pack64(encrypt(data, passphrase)) | |
end | ||
# Decrypt and base-64 decode the given data with the given passphrase. | ||
# Returns the decoded result or 'nil' on error. | ||
# | ||
def decode(data, passphrase) | ||
121 | | |
150 | decrypt(unpack64(data), passphrase) | |
rescue | ||
return nil | ||
end | ||
... | ... | |
# particular order. | ||
# | ||
ROLES = { | ||
197 | | |
198 | | |
199 | | |
200 | | |
226 | :admin => 'Administrator', | |
227 | :webmaster => 'Webmaster', | |
228 | :privileged => 'Advanced user', | |
229 | :normal => 'Normal user' | |
} | ||
ADMIN = :admin | ||
... | ... | |
# classes are extended with to_authenticated_roles methods, which | ||
# provide other ways of creating Roles objects. | ||
# | ||
231 | | |
232 | | |
260 | def initialize(admin = false) | |
261 | if (admin) | |
@role_array = [ ADMIN ] | ||
else | ||
@role_array = [ NORMAL ] | ||
... | ... | |
human_names.push(HubSsoLib::Roles.get_display_name(role)) | ||
end | ||
280 | | |
309 | if (human_names.length == 0) | |
310 | return '' | |
311 | elsif (human_names.length == 1) | |
312 | return human_names[0] | |
313 | else | |
314 | return human_names[0..-2].join(', ') + ' and ' + human_names.last | |
315 | end | |
end | ||
# Do nothing - this is just useful for polymorphic code, where a function | ||
... | ... | |
# Initialize a permissions object. The map is a hash which maps action | ||
# names, expressed as symbols, to roles, expressed as individual symbols, | ||
# equivalent strings, or arrays of multiple strings or symbols. Use 'nil' | ||
351 | | |
386 | # to indicate permission for the general public - no login required - or | |
387 | # simply omit the action (unlisted actions are permitted). | |
# | ||
353 | | |
354 | | |
355 | | |
356 | | |
357 | | |
389 | # Example mapping for a generic controller: | |
# | ||
359 | | |
360 | | |
361 | | |
362 | | |
363 | | |
364 | | |
365 | | |
366 | | |
367 | | |
391 | # { | |
392 | # :new => [ :admin, :webmaster, :privileged, :normal ], | |
393 | # :create => [ :admin, :webmaster, :privileged, :normal ], | |
394 | # :edit => [ :admin, :webmaster, :privileged, :normal ], | |
395 | # :update => [ :admin, :webmaster, :privileged, :normal ], | |
396 | # :delete => [ :admin, :webmaster, :privileged ], | |
397 | # :list => nil, | |
398 | # :show => nil | |
399 | # } | |
400 | # | |
401 | def initialize(pmap) | |
@permissions = pmap | ||
end | ||
... | ... | |
# it to a Roles object internally (so you could pass a role symbol, | ||
# string, array of symbols or strings, or comma-separated string). | ||
# | ||
412 | # Passing an empty roles string will tell you whether or not the | |
413 | # action requires login. Only actions not in the permissions list or | |
414 | # those with a 'nil' list of roles will generate a result 'true', | |
415 | # since any other actions will require your empty roles string to | |
416 | # include at least one role (which it obviously doesn't). | |
417 | # | |
def permitted?(roles, action) | ||
action = action.to_s.intern | ||
roles = roles.to_authenticated_roles | ||
382 | | |
422 | return true unless @permissions.include?(action) | |
return true if @permissions[action].nil? | ||
return roles.include?(@permissions[action]) | ||
end | ||
386 | ||
end # Permissions class | ||
####################################################################### | ||
429 | # Module: User # | |
430 | # By Hipposoft, 2006 # | |
431 | # # | |
432 | # Purpose: A representation of the Hub application's User Model in # | |
433 | # terms of a simple set of properties, so that applications # | |
434 | # don't need User access to understand user attributes. # | |
435 | # # | |
436 | # Author: A.D.Hodgkinson # | |
437 | # # | |
438 | # History: 21-Oct-2006 (ADH): Created. # | |
439 | ####################################################################### | |
440 | ||
441 | class User | |
442 | attr_accessor :salt | |
443 | attr_accessor :roles | |
444 | attr_accessor :updated_at | |
445 | attr_accessor :activated_at | |
446 | attr_accessor :real_name | |
447 | attr_accessor :crypted_password | |
448 | attr_accessor :remember_token_expires_at | |
449 | attr_accessor :activation_code | |
450 | attr_accessor :member_id | |
451 | attr_accessor :id | |
452 | attr_accessor :password_reset_code | |
453 | attr_accessor :remember_token | |
454 | attr_accessor :email | |
455 | attr_accessor :created_at | |
456 | attr_accessor :password_reset_code_expires_at | |
457 | ||
458 | def initialize | |
459 | self.salt = nil | |
460 | self.roles = nil | |
461 | self.updated_at = nil | |
462 | self.activated_at = nil | |
463 | self.real_name = nil | |
464 | self.crypted_password = nil | |
465 | self.remember_token_expires_at = nil | |
466 | self.activation_code = nil | |
467 | self.member_id = nil | |
468 | self.id = nil | |
469 | self.password_reset_code = nil | |
470 | self.remember_token = nil | |
471 | self.email = nil | |
472 | self.created_at = nil | |
473 | self.password_reset_code_expires_at = nil | |
474 | end | |
475 | end | |
476 | ||
477 | ####################################################################### | |
478 | # Module: SessionData # | |
479 | # By Hipposoft, 2006 # | |
480 | # # | |
481 | # Purpose: Session support object, used to store session metadata in # | |
482 | # an insecure cross-application cookie. # | |
483 | # # | |
484 | # Author: A.D.Hodgkinson # | |
485 | # # | |
486 | # History: 22-Oct-2006 (ADH): Created. # | |
487 | ####################################################################### | |
488 | ||
489 | class SessionData | |
490 | attr_accessor :last_used | |
491 | attr_accessor :return_to | |
492 | attr_accessor :flash | |
493 | ||
494 | def initialize | |
495 | self.last_used = Time.now.utc | |
496 | self.return_to = nil | |
497 | self.flash = {} | |
498 | end | |
499 | end | |
500 | ||
501 | ####################################################################### | |
# Module: Core # | ||
# Various authors # | ||
# # | ||
... | ... | |
module Core | ||
# Returns true or false if the user is logged in. | ||
406 | | |
518 | # | |
519 | # Preloads @hubssolib_current_user with user data if logged in. | |
520 | # | |
def hubssolib_logged_in? | ||
408 | | |
522 | user = self.hubssolib_current_user | |
523 | return user && user != :false ? true : false | |
end | ||
411 | | |
412 | | |
413 | | |
414 | | |
415 | ||
416 | | |
417 | | |
418 | | |
419 | | |
420 | | |
421 | ||
# Check if the user is authorized to perform the current action. If calling | ||
# from a helper, pass the action name and class name; otherwise by default, | ||
# the current action name and 'self.class' will be used. | ||
... | ... | |
# compared against the caller's permissions hash and the action name. | ||
# | ||
def hubssolib_authorized?(action = action_name, classname = self.class) | ||
431 | | |
535 | ||
536 | # Classes with no permissions object always authorise everything. | |
537 | # Otherwise, ask the permissions object for its opinion. | |
538 | ||
539 | if (classname.respond_to? :hubssolib_permissions) | |
540 | return classname.hubssolib_permissions.permitted?(self.hubssolib_current_user.roles, action) | |
541 | else | |
542 | return true | |
543 | end | |
end | ||
434 | | |
546 | # Is the current user privileged? Anything other than normal user | |
547 | # privileges will suffice. Can be called if not logged in. Returns | |
548 | # 'false' for logged out or normal user privileges only, else 'true'. | |
# | ||
436 | | |
550 | def hubssolib_privileged? | |
551 | return false unless hubssolib_logged_in? | |
552 | ||
553 | pnormal = HubSsoLib::Roles.new(false).to_s | |
554 | puser = self.hubssolib_current_user.roles.to_authenticated_roles.to_s | |
555 | ||
556 | return (puser && !puser.empty? && puser != pnormal) | |
557 | end | |
558 | ||
559 | # Log out the user. Very few applications should ever need to call this, | |
560 | # though Hub certainly does and it gets used internally too. | |
# | ||
438 | | |
562 | def hubssolib_log_out | |
563 | # Causes the "hubssolib_current_user=" method to run, which | |
564 | # deals with everything else. | |
565 | self.hubssolib_current_user = nil | |
566 | end | |
567 | ||
568 | # Accesses the current user from the cookie or internal cache. | |
569 | # The cache is used because of the IMHO horrible Rails cookie | |
570 | # API - a value we set right now, then read back, does not get | |
571 | # returned. The values we read are from the last browser | |
572 | # response, always; the values we set are to be sent out upon | |
573 | # the next browser request, always. This means we can't just | |
574 | # set values in the cookie and rely on being able to read them | |
575 | # later, but before another request has been processed. Hence | |
576 | # the cache. | |
# | ||
440 | | |
578 | def hubssolib_current_user | |
579 | @hubssolib_current_user ||= hubssolib_get_user_data | |
580 | end | |
581 | ||
582 | # Store the given user data in the cookie | |
# | ||
442 | | |
584 | def hubssolib_current_user=(new_user) | |
585 | # We have to distinguish between "code just started running, | |
586 | # @hubssolib_current_user not defined yet" and "someone set | |
587 | # the user to 'nil' to log out" states. We do this by setting | |
588 | # a user value of :false, a symbol, so that "user ||= thing" | |
589 | # will continue to return ":false" rather than "thing". | |
590 | ||
591 | @hubssolib_current_user = new_user || :false | |
592 | hubssolib_set_user_data(new_user) | |
593 | end | |
594 | ||
595 | # Accesses the current session from the cookie. Creates a new | |
596 | # session object if need be. | |
# | ||
444 | | |
598 | def hubssolib_current_session | |
599 | @hubssolib_current_session ||= hubssolib_get_session_data || HubSsoLib::SessionData.new | |
600 | end | |
601 | ||
602 | # Store the given session data in the cookie | |
# | ||
446 | | |
604 | def hubssolib_current_session=(new_session) | |
605 | @hubssolib_current_session = new_session | |
606 | hubssolib_set_session_data(new_session) | |
607 | end | |
608 | ||
609 | # Return a human-readable unique ID for a user. We don't want to | |
610 | # have e-mail addresses all over the place, but don't want to rely | |
611 | # on real names as unique - they aren't. Instead, produce a | |
612 | # composite of the user's account database ID (which must be | |
613 | # unique by definition) and their real name. | |
# | ||
448 | | |
449 | | |
450 | | |
451 | | |
452 | | |
453 | | |
615 | def hubssolib_unique_name | |
616 | user = hubssolib_current_user | |
617 | user ? "#{user.real_name} (#{user.id})" : 'Anonymous' | |
618 | end | |
455 | | |
456 | | |
457 | | |
620 | # Main filter method to implement HubSsoLib permissions management, | |
621 | # session expiry and so-on. Called from controllers only. | |
622 | # | |
623 | def hubssolib_update_state | |
624 | ||
625 | # Does this action require a logged in user? | |
626 | ||
627 | if (self.class.respond_to? :hubssolib_permissions) | |
628 | login_is_required = !self.class.hubssolib_permissions.permitted?('', action_name) | |
629 | else | |
630 | login_is_required = false | |
end | ||
459 | | |
461 | | |
462 | | |
633 | # If we require login but we're logged out, redirect to Hub login. | |
464 | | |
465 | | |
466 | | |
467 | | |
635 | logged_in = hubssolib_logged_in? | |
469 | | |
470 | | |
471 | | |
472 | | |
473 | | |
474 | | |
475 | | |
476 | | |
477 | | |
478 | | |
479 | | |
480 | | |
481 | | |
482 | | |
483 | | |
637 | if (login_is_required and logged_in == false) | |
638 | hubssolib_store_location | |
639 | return hubssolib_must_login | |
640 | end | |
641 | ||
642 | # If we reach here the user is either logged, or the method does | |
643 | # not require them to be. In the latter case, if we're not logged | |
644 | # in there is no more work to do - exit early. | |
645 | ||
646 | return true unless logged_in # true -> let action processing continue | |
647 | ||
648 | # So we reach here knowing we're logged in, but the action may or | |
649 | # may not require authorisation. | |
650 | ||
651 | unless (login_is_required) | |
652 | ||
653 | # We have to update session expiry even for actions that don't | |
654 | # need us to be logged in, since we *are* logged in and need to | |
655 | # maintain that state. If, though, the session expires, we just | |
656 | # quietly log out and let action processing carry on. | |
657 | ||
658 | if (hubssolib_session_expired?) | |
659 | hubssolib_log_out | |
660 | hubssolib_set_flash(:attention, 'Your session timed out, so you are no longer logged in.') | |
661 | else | |
662 | hubssolib_set_last_used(Time.now.utc) | |
663 | end | |
664 | ||
665 | return true # true -> let action processing continue | |
666 | ||
667 | else | |
668 | ||
669 | # Login *is* required for this action. If the session expires, | |
670 | # redirect to Hub's login page via its expiry action. Otherwise | |
671 | # check authorisation and allow action processing to continue | |
672 | # if OK, else indicate that access is denied. | |
673 | ||
674 | if (hubssolib_session_expired?) | |
675 | hubssolib_store_location | |
676 | hubssolib_log_out | |
677 | hubssolib_set_flash(:attention, 'Sorry, your session timed out; you need to log in again to continue.') | |
678 | ||
# We mean this: redirect_to :controller => 'account', :action => 'login' | ||
# ...except for the Hub, rather than the current application (whatever | ||
# it may be). | ||
487 | | |
488 | | |
489 | | |
490 | | |
491 | | |
492 | | |
493 | | |
494 | | |
495 | | |
682 | redirect_to HUB_PATH_PREFIX + '/account/login' | |
683 | else | |
684 | hubssolib_set_last_used(Time.now.utc) | |
685 | return hubssolib_authorized? ? true : hubssolib_access_denied | |
686 | end | |
687 | ||
688 | end | |
end | ||
# Store the URI of the current request in the session. | ||
# | ||
# We can return to this location by calling #redirect_back_or_default. | ||
def hubssolib_store_location | ||
502 | | |
695 | hubssolib_set_return_to(request.request_uri) | |
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) | ||
508 | | |
509 | | |
701 | url = hubssolib_get_return_to | |
702 | ||
703 | url ? redirect_to_url(url) : redirect_to(default) | |
704 | hubssolib_set_return_to(nil) | |
end | ||
# Ensure the current request is carried out over HTTPS by redirecting | ||
... | ... | |
redirect_to({ :protocol => 'https://' }) unless request.ssl? | ||
end | ||
519 | | |
520 | | |
521 | | |
522 | | |
714 | # Public methods to set some data that would normally go in @session, | |
715 | # but can't because it needs to be accessed across applications. It is | |
716 | # put in an insecure support cookie instead. There are some related | |
717 | # private methods for things like session expiry too. | |
718 | # | |
719 | def hubssolib_get_flash() | |
720 | hubssolib_get_field(:flash) || {} | |
end | ||
525 | | |
723 | def hubssolib_set_flash(symbol, message) | |
724 | f = hubssolib_get_flash | |
725 | f[symbol] = message | |
726 | hubssolib_set_field(:flash=, f) | |
727 | end | |
728 | ||
729 | def hubssolib_clear_flash | |
730 | hubssolib_set_field(:flash=, {}) | |
731 | end | |
732 | ||
733 | # Helper methods to output flash data. It isn't merged into the standard | |
734 | # application flash with a filter because the rather daft and difficult | |
735 | # to manage lifecycle model of the standard flash gets in the way. | |
# | ||
527 | | |
528 | | |
529 | | |
530 | | |
531 | | |
532 | | |
533 | | |
534 | | |
535 | | |
536 | | |
537 | | |
538 | | |
737 | # First, return tags for a flash using the given key, clearing the | |
738 | # result in the flash hash now it has been used. | |
739 | # | |
740 | def hubssolib_flash_tag(key) | |
741 | value = hubssolib_get_flash()[key] | |
540 | | |
743 | if (value) | |
744 | hubssolib_set_flash(key, nil) | |
745 | return "<h2 align=\"left\" class=\"#{key}\">#{value}</h2><p />" | |
746 | else | |
747 | return '' | |
748 | end | |
749 | end | |
542 | | |
543 | | |
751 | # Return tags for a standard application flash using the given key. | |
# | ||
545 | | |
753 | def hubssolib_standard_flash_tag(key) | |
754 | value = flash[key] if (flash) | |
547 | | |
548 | ||
549 | | |
550 | | |
551 | | |
552 | | |
553 | | |
554 | | |
756 | if (value) | |
757 | flash.delete(key) | |
758 | return "<h2 align=\"left\" class=\"#{key}\">#{value}</h2><p />" | |
else | ||
556 | | |
760 | return '' | |
end | ||
end | ||
560 | | |
764 | # Return flash tags for known keys, then all remaining keys, from both | |
765 | # the cross-application and standard standard flash hashes. | |
# | ||
562 | | |
563 | | |
564 | | |
565 | | |
566 | | |
567 | | |
568 | | |
569 | | |
570 | | |
571 | | |
572 | | |
767 | def hubssolib_flash_tags | |
768 | # These known key values are used to guarantee an order in the output | |
769 | # for cases where multiple messages are defined. | |
770 | ||
771 | tags = hubssolib_flash_tag(:notice) << | |
772 | hubssolib_flash_tag(:attention) << | |
773 | hubssolib_flash_tag(:alert) | |
774 | ||
775 | tags << hubssolib_standard_flash_tag(:notice) << | |
776 | hubssolib_standard_flash_tag(:attention) << | |
777 | hubssolib_standard_flash_tag(:alert) | |
778 | ||
779 | # Now pick up anything else. | |
780 | ||
781 | hubssolib_get_flash.each do |key, value| | |
782 | tags << hubssolib_flash_tag(key) if (value) | |
783 | end | |
784 | ||
785 | flash.each do |key, value| | |
786 | tags << hubssolib_standard_flash_tag(key) if (value) | |
787 | end | |
788 | ||
789 | return tags | |
790 | end | |
791 | ||
792 | # Inclusion hook to make various methods available as ActionView | |
793 | # helper methods. | |
794 | def self.included(base) | |
795 | base.send :helper_method, | |
796 | :hubssolib_current_user, | |
797 | :hubssolib_logged_in?, | |
798 | :hubssolib_authorized?, | |
799 | :hubssolib_privileged?, | |
800 | :hubssolib_flash_tags | |
801 | end | |
802 | ||
803 | private | |
804 | ||
805 | # Indicate that the user must log in to complete their request. | |
806 | # Returns false to enable a before_filter to return through this | |
807 | # method while ensuring that the previous action processing is | |
808 | # halted (since the overall return value is therefore 'false'). | |
# | ||
574 | | |
575 | | |
576 | | |
577 | | |
578 | | |
579 | | |
810 | def hubssolib_must_login | |
811 | hubssolib_set_flash(:alert, 'You must log in before you can continue.') | |
812 | redirect_to HUB_PATH_PREFIX + '/account/login' | |
813 | return false | |
814 | end | |
581 | | |
816 | # Indicate access is denied for a given logged in user's request. | |
817 | # Returns false to enable a before_filter to return through this | |
818 | # method while ensuring that the previous action processing is | |
819 | # halted (since the overall return value is therefore 'false'). | |
# | ||
583 | | |
584 | | |
821 | def hubssolib_access_denied | |
822 | hubssolib_set_flash(:alert, 'You do not have permission to carry out that action on this site.') | |
823 | redirect_to HUB_PATH_PREFIX + '/' | |
824 | return false | |
825 | end | |
826 | ||
827 | # Check conditions for session expiry. Returns 'true' if session's | |
828 | # last_used date indicates expiry, else 'false'. | |
829 | # | |
830 | def hubssolib_session_expired? | |
831 | ||
832 | # 23-Oct-2006 (ADH): | |
833 | # | |
834 | # An exception, which is also a security hole of sorts. POST requests | |
835 | # cannot be redirected because HTTP doesn't have that concept. If a user | |
836 | # is editing a Wiki page, say, then goes away, comes back later and now | |
837 | # finishes their edits, their session may have timed out. They submit | |
838 | # the page but it's by POST so their submission details are lost. If they | |
839 | # are lucky their browser might remember the form contents if they go | |
840 | # back but not all do and not all users would think of doing that. | |
841 | # | |
842 | # To work around this, don't enforce a timeout for POST requests. Should | |
843 | # a user on a public computer not log out, then a hacker arrive *after* | |
844 | # the session expiry time (if they arrive before it expires then the | |
845 | # except for POSTs is irrelevant), they could recover the session by | |
846 | # constructing a POST request. It's a convoluted path, requires a user to | |
847 | # have not logged out anyway, and the Hub isn't intended for Fort Knox. | |
848 | # At the time of writing the trade-off of usability vs security is | |
849 | # considered acceptable, though who knows, the view may change in future. | |
850 | ||
851 | last_used = hubssolib_get_last_used | |
852 | (request.method != :post && last_used && Time.now.utc - last_used > HUBSSOLIB_IDLE_TIME_LIMIT) | |
853 | end | |
854 | ||
855 | # Retrieve data from a given cookie with encrypted contents. | |
856 | # | |
857 | def hubssolib_get_cookie_data(name) | |
858 | crypto = HubSsoLib::Crypto.new(HUBSSOLIB_RND_FILE_PATH) | |
passphrase = crypto.scramble_passphrase(request.remote_ip) | ||
586 | | |
860 | data = cookies[name] | |
user = nil | ||
589 | | |
863 | if (data && !data.empty?) | |
user = Marshal.load(crypto.decode(data, passphrase)) | ||
end | ||
... | ... | |
return nil | ||
end | ||
598 | | |
599 | | |
872 | # Set the given cookie to a value of the given data, which | |
873 | # will be encrypted. | |
# | ||
601 | | |
602 | | |
603 | | |
604 | | |
875 | def hubssolib_set_cookie_data(name, value) | |
876 | if (value.nil?) | |
877 | # Using cookies.delete *should* work but doesn't. Set the | |
878 | # cookie with nil data instead. | |
data = nil | ||
else | ||
607 | | |
881 | crypto = HubSsoLib::Crypto.new(HUBSSOLIB_RND_FILE_PATH) | |
passphrase = crypto.scramble_passphrase(request.remote_ip) | ||
609 | | |
883 | data = crypto.encode(Marshal.dump(value), passphrase) | |
end | ||
612 | | |
613 | | |
614 | | |
615 | | |
616 | | |
617 | | |
886 | # No expiry time; to aid security, use session cookies only. | |
887 | ||
888 | cookies[name] = { | |
889 | :value => data, | |
890 | :path => '/rails', | |
891 | :secure => true | |
892 | } | |
end | ||
895 | # Retrieve user data from the session data cookie. | |
896 | # | |
897 | def hubssolib_get_user_data | |
898 | return hubssolib_get_cookie_data(HUBSSOLIB_SESSION_DATA_KEY) | |
899 | end | |
900 | ||
901 | # Store user data in the session data cookie. Pass the user to store, | |
902 | # or 'nil' to clear the cookie. | |
903 | # | |
904 | def hubssolib_set_user_data(user) | |
905 | hubssolib_set_cookie_data(HUBSSOLIB_SESSION_DATA_KEY, user) | |
906 | end | |
907 | ||
908 | # Retrieve session data from the session support cookie. | |
909 | # | |
910 | def hubssolib_get_session_data | |
911 | return hubssolib_get_cookie_data(HUBSSOLIB_SESSION_SUPPORT_KEY) | |
912 | end | |
913 | ||
914 | # Store session data in the session support cookie. Pass the session | |
915 | # tostore, or 'nil' to clear the cookie. | |
916 | # | |
917 | def hubssolib_set_session_data(support) | |
918 | hubssolib_set_cookie_data(HUBSSOLIB_SESSION_SUPPORT_KEY, support) | |
919 | end | |
920 | ||
921 | # Retrieve data from the session support cookie, with lazy initialisation. | |
922 | # | |
923 | def hubssolib_get_field(field) | |
924 | data = self.hubssolib_current_session | |
925 | return data.send(field) | |
926 | rescue | |
927 | return nil | |
928 | end | |
929 | ||
930 | # Set data in the session support cookie, merging with existing values and | |
931 | # supporting lazy initialisation. Returns 'true' if successful, else 'false'. | |
932 | # | |
933 | def hubssolib_set_field(field, value) | |
934 | data = self.hubssolib_current_session | |
935 | data.send(field, value) | |
936 | self.hubssolib_current_session = data | |
937 | ||
938 | return true | |
939 | rescue | |
940 | return false | |
941 | end | |
942 | ||
943 | # Methods for session support using an independent, insecure cookie. | |
944 | ||
945 | def hubssolib_get_last_used | |
946 | hubssolib_get_field(:last_used) | |
947 | end | |
948 | ||
949 | def hubssolib_set_last_used(time) | |
950 | hubssolib_set_field(:last_used=, time) | |
951 | end | |
952 | ||
953 | def hubssolib_get_return_to | |
954 | hubssolib_get_field(:return_to) | |
955 | end | |
956 | ||
957 | def hubssolib_set_return_to(url) | |
958 | hubssolib_set_field(:return_to=, url) | |
959 | end | |
960 | ||
end # Core module | ||
end # HubSsoLib module | ||