your_platform 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +39 -11
- data/Rakefile +15 -1
- data/app/assets/images/file.png +0 -0
- data/app/assets/images/img/excel2013_file_128.png +0 -0
- data/app/assets/images/img/excel2013_file_bw_107.png +0 -0
- data/app/assets/images/img/excel2013_file_bw_semitransparent_107.png +0 -0
- data/app/assets/images/img/glyphicons-halflings-white.png +0 -0
- data/app/assets/images/img/glyphicons-halflings.png +0 -0
- data/app/assets/images/img/gmaps_yellow_marker.png +0 -0
- data/app/assets/images/img/gmaps_yellow_marker_38.png +0 -0
- data/app/assets/images/markdown_help.png +0 -0
- data/app/assets/images/your_platform/breadcrumb-sep.png +0 -0
- data/app/assets/javascripts/app-ng.js.coffee +5 -0
- data/app/assets/javascripts/attachments.js +2 -0
- data/app/assets/javascripts/controllers-ng/bookmark_list_controller.js.coffee +30 -0
- data/app/assets/javascripts/controllers-ng/box_controller.js.coffee +37 -0
- data/app/assets/javascripts/controllers-ng/profile_angular.js.coffee +151 -0
- data/app/assets/javascripts/directives-ng/box_directive.js.coffee +91 -0
- data/app/assets/javascripts/directives-ng/star_tool_directive.js.coffee +111 -0
- data/app/assets/javascripts/filters-ng/some_filter.js.coffee +0 -0
- data/app/assets/javascripts/jquery.appear-1.1.1.js +138 -0
- data/app/assets/javascripts/make-js-more-like-ruby.js.coffee +32 -0
- data/app/assets/javascripts/mercury.js +456 -0
- data/app/assets/javascripts/models-ng/bookmark.js.coffee +28 -0
- data/app/assets/javascripts/services-ng/current_user_bookmarks.js.coffee +39 -0
- data/app/assets/javascripts/your_platform.js +27 -0
- data/app/assets/javascripts/your_platform/address_labels.js.coffee +40 -0
- data/app/assets/javascripts/your_platform/attachments.js.coffee +61 -0
- data/app/assets/javascripts/your_platform/auto-completion.js.coffee +90 -0
- data/app/assets/javascripts/your_platform/best_in_place.js.coffee +8 -0
- data/app/assets/javascripts/your_platform/best_in_place_hyperlinks.js.coffee +25 -0
- data/app/assets/javascripts/your_platform/best_in_place_tab_key.js.coffee +28 -0
- data/app/assets/javascripts/your_platform/boxes.js.coffee +11 -0
- data/app/assets/javascripts/your_platform/change_password.js.coffee +22 -0
- data/app/assets/javascripts/your_platform/close_dropdowns.js.coffee +18 -0
- data/app/assets/javascripts/your_platform/copy_to_clipboard.js.coffee +6 -0
- data/app/assets/javascripts/your_platform/datatables.coffee +112 -0
- data/app/assets/javascripts/your_platform/datepicker_settings.js.coffee +16 -0
- data/app/assets/javascripts/your_platform/edit_tools.js.coffee +19 -0
- data/app/assets/javascripts/your_platform/editable_dbl_click.js.coffee +42 -0
- data/app/assets/javascripts/your_platform/events.js.coffee +126 -0
- data/app/assets/javascripts/your_platform/fix_textarea.js.coffee +11 -0
- data/app/assets/javascripts/your_platform/galleria.js.coffee +112 -0
- data/app/assets/javascripts/your_platform/groups.js.coffee +36 -0
- data/app/assets/javascripts/your_platform/hidden.js.coffee +5 -0
- data/app/assets/javascripts/your_platform/links_to_external_sites.js.coffee +12 -0
- data/app/assets/javascripts/your_platform/maps.js.coffee +13 -0
- data/app/assets/javascripts/your_platform/may_need_review.js.coffee +10 -0
- data/app/assets/javascripts/your_platform/navable_title_rename.js.coffee +17 -0
- data/app/assets/javascripts/your_platform/officers.js.coffee +35 -0
- data/app/assets/javascripts/your_platform/popovers.js.coffee +38 -0
- data/app/assets/javascripts/your_platform/posts.js.coffee +58 -0
- data/app/assets/javascripts/your_platform/profile_fields.js.coffee +61 -0
- data/app/assets/javascripts/your_platform/search.js.coffee +26 -0
- data/app/assets/javascripts/your_platform/tooltips.js.coffee +10 -0
- data/app/assets/javascripts/your_platform/turbolinks_loading_spinner.js.coffee +83 -0
- data/app/assets/javascripts/your_platform/user_avatars.js.coffee +33 -0
- data/app/assets/javascripts/your_platform/user_group_memberships.js.coffee +11 -0
- data/app/assets/javascripts/your_platform/user_settings.js.coffee +18 -0
- data/app/assets/javascripts/your_platform/users_new.js.coffee +54 -0
- data/app/assets/stylesheets/bootstrap_layout.css.sass +3 -0
- data/app/assets/stylesheets/bootstrap_layout/attachments.css.sass +3 -0
- data/app/assets/stylesheets/bootstrap_layout/boxes.css.sass +11 -0
- data/app/assets/stylesheets/bootstrap_layout/breadcrumb.css.sass +25 -0
- data/app/assets/stylesheets/bootstrap_layout/category_indicator.css.sass +5 -0
- data/app/assets/stylesheets/bootstrap_layout/footer.css.sass +14 -0
- data/app/assets/stylesheets/bootstrap_layout/galleria.css.sass +8 -0
- data/app/assets/stylesheets/bootstrap_layout/header_bar.css.sass +11 -0
- data/app/assets/stylesheets/bootstrap_layout/headings.css.sass +10 -0
- data/app/assets/stylesheets/bootstrap_layout/logged_in_bar.css.sass +40 -0
- data/app/assets/stylesheets/bootstrap_layout/logo.css.sass +2 -0
- data/app/assets/stylesheets/bootstrap_layout/modal_fix.css.sass +8 -0
- data/app/assets/stylesheets/bootstrap_layout/profiles.css.sass +10 -0
- data/app/assets/stylesheets/bootstrap_layout/session_bar.css.sass +60 -0
- data/app/assets/stylesheets/bootstrap_layout/stars.css.sass +4 -0
- data/app/assets/stylesheets/bootstrap_layout/turbolinks_progress_bar.css.sass +3 -0
- data/app/assets/stylesheets/bootstrap_layout/vertical_menu.css.sass +15 -0
- data/app/assets/stylesheets/bootstrap_setup.css.sass +4 -0
- data/app/assets/stylesheets/your_platform.css.sass +11 -0
- data/app/assets/stylesheets/your_platform/address_labels_modal.css.sass +8 -0
- data/app/assets/stylesheets/your_platform/attachments.css.sass +75 -0
- data/app/assets/stylesheets/your_platform/authorization_info.css.sass +16 -0
- data/app/assets/stylesheets/your_platform/auto-completion.css.sass +3 -0
- data/app/assets/stylesheets/your_platform/center.css.sass +14 -0
- data/app/assets/stylesheets/your_platform/change_password.css.sass +13 -0
- data/app/assets/stylesheets/your_platform/corporate_vita.css.sass +2 -0
- data/app/assets/stylesheets/your_platform/datatables.css.sass +23 -0
- data/app/assets/stylesheets/your_platform/datepicker.css.sass +2 -0
- data/app/assets/stylesheets/your_platform/dropdowns.css.sass +8 -0
- data/app/assets/stylesheets/your_platform/events.css.sass +68 -0
- data/app/assets/stylesheets/your_platform/forms.css.sass +25 -0
- data/app/assets/stylesheets/your_platform/galleria.css.sass +12 -0
- data/app/assets/stylesheets/your_platform/groups.css.sass +8 -0
- data/app/assets/stylesheets/your_platform/groups_table.css.sass +8 -0
- data/app/assets/stylesheets/your_platform/hidden.css.sass +3 -0
- data/app/assets/stylesheets/your_platform/images.css.sass +50 -0
- data/app/assets/stylesheets/your_platform/last_activities.css.sass +17 -0
- data/app/assets/stylesheets/your_platform/latest_members.css.sass +7 -0
- data/app/assets/stylesheets/your_platform/login.css.sass +4 -0
- data/app/assets/stylesheets/your_platform/maps.css.sass +22 -0
- data/app/assets/stylesheets/your_platform/markdown_help.css.sass +5 -0
- data/app/assets/stylesheets/your_platform/may_need_review.css.sass +3 -0
- data/app/assets/stylesheets/your_platform/pages.css.sass +12 -0
- data/app/assets/stylesheets/your_platform/password_strength.css.sass +73 -0
- data/app/assets/stylesheets/your_platform/picture_attachments.css.sass +7 -0
- data/app/assets/stylesheets/your_platform/popovers.css.sass +13 -0
- data/app/assets/stylesheets/your_platform/posts.css.sass +32 -0
- data/app/assets/stylesheets/your_platform/profiles.css.sass +153 -0
- data/app/assets/stylesheets/your_platform/search_preview.css.sass +4 -0
- data/app/assets/stylesheets/your_platform/star_tool.css.sass +2 -0
- data/app/assets/stylesheets/your_platform/tooltips.css.sass +7 -0
- data/app/assets/stylesheets/your_platform/turbolinks_loading_spinner.css.sass +3 -0
- data/app/assets/stylesheets/your_platform/user_avatars.css.sass +8 -0
- data/app/assets/stylesheets/your_platform/user_group_memberships.css.sass +4 -0
- data/app/assets/stylesheets/your_platform/vertical_nav.css.sass +7 -0
- data/app/controllers/activities_controller.rb +6 -0
- data/app/controllers/application_controller.rb +236 -0
- data/app/controllers/attachments_controller.rb +97 -0
- data/app/controllers/blog_posts_controller.rb +50 -0
- data/app/controllers/bookmarks_controller.rb +33 -0
- data/app/controllers/corporations_controller.rb +22 -0
- data/app/controllers/errors_controller.rb +27 -0
- data/app/controllers/events_controller.rb +262 -0
- data/app/controllers/groups_controller.rb +257 -0
- data/app/controllers/officers_controller.rb +28 -0
- data/app/controllers/pages_controller.rb +67 -0
- data/app/controllers/posts_controller.rb +81 -0
- data/app/controllers/profile_fields_controller.rb +132 -0
- data/app/controllers/root_controller.rb +35 -0
- data/app/controllers/search_controller.rb +149 -0
- data/app/controllers/sessions_controller.rb +21 -0
- data/app/controllers/setup_controller.rb +80 -0
- data/app/controllers/statistics_controller.rb +38 -0
- data/app/controllers/status_group_memberships_controller.rb +28 -0
- data/app/controllers/terms_of_use_controller.rb +35 -0
- data/app/controllers/user_accounts_controller.rb +55 -0
- data/app/controllers/user_group_memberships_controller.rb +75 -0
- data/app/controllers/user_settings_controller.rb +57 -0
- data/app/controllers/users_controller.rb +125 -0
- data/app/controllers/workflows_controller.rb +19 -0
- data/app/helpers/application_helper.rb +25 -0
- data/app/helpers/attachments_helper.rb +2 -0
- data/app/helpers/auto_completion_helper.rb +33 -0
- data/app/helpers/avatar_helper.rb +70 -0
- data/app/helpers/bookmarks_helper.rb +22 -0
- data/app/helpers/box_helper.rb +56 -0
- data/app/helpers/breadcrumbs_helper.rb +62 -0
- data/app/helpers/corporate_vita_helper.rb +34 -0
- data/app/helpers/events_helper.rb +28 -0
- data/app/helpers/flash_helper.rb +60 -0
- data/app/helpers/footer_helper.rb +13 -0
- data/app/helpers/galleria_helper.rb +13 -0
- data/app/helpers/groups_helper.rb +66 -0
- data/app/helpers/horizontal_nav_helper.rb +11 -0
- data/app/helpers/i18n_helper.rb +10 -0
- data/app/helpers/icon_helper.rb +35 -0
- data/app/helpers/mailer_helper.rb +7 -0
- data/app/helpers/map_helper.rb +26 -0
- data/app/helpers/markdown_helper.rb +22 -0
- data/app/helpers/markup_helper.rb +25 -0
- data/app/helpers/officers_helper.rb +13 -0
- data/app/helpers/password_helper.rb +23 -0
- data/app/helpers/profile_field_helper.rb +40 -0
- data/app/helpers/profile_helper.rb +69 -0
- data/app/helpers/quick_link_helper.rb +53 -0
- data/app/helpers/special_pages_helper.rb +9 -0
- data/app/helpers/structureable_helper.rb +11 -0
- data/app/helpers/sublime_helper.rb +16 -0
- data/app/helpers/title_helper.rb +52 -0
- data/app/helpers/tool_buttons_helper.rb +74 -0
- data/app/helpers/unicode_helper.rb +9 -0
- data/app/helpers/users_helper.rb +13 -0
- data/app/helpers/vertical_nav_helper.rb +84 -0
- data/app/helpers/workflows_helper.rb +37 -0
- data/app/mailers/event_mailer.rb +13 -0
- data/app/mailers/post_mailer.rb +11 -0
- data/app/mailers/user_account_mailer.rb +17 -0
- data/app/models/ability.rb +321 -0
- data/app/models/active_record_associations_patches.rb +26 -0
- data/app/models/active_record_cache_extension.rb +152 -0
- data/app/models/active_record_find_by_extension.rb +20 -0
- data/app/models/active_record_json_url_extension.rb +51 -0
- data/app/models/active_record_metric_events_extension.rb +22 -0
- data/app/models/active_record_read_only_extension.rb +35 -0
- data/app/models/active_record_update_attributes_bip_extension.rb +24 -0
- data/app/models/address_label.rb +50 -0
- data/app/models/app_version.rb +49 -0
- data/app/models/array.rb +15 -0
- data/app/models/attachment.rb +76 -0
- data/app/models/bashpass_password.rb +32 -0
- data/app/models/blog_post.rb +2 -0
- data/app/models/bookmark.rb +67 -0
- data/app/models/cache_additions.rb +15 -0
- data/app/models/cache_store_extension.rb +78 -0
- data/app/models/concerns/user_avatar.rb +16 -0
- data/app/models/concerns/user_corporations.rb +44 -0
- data/app/models/concerns/user_date_of_birth.rb +74 -0
- data/app/models/concerns/user_profile.rb +102 -0
- data/app/models/corporation.rb +80 -0
- data/app/models/dag_link.rb +29 -0
- data/app/models/event.rb +235 -0
- data/app/models/flag.rb +18 -0
- data/app/models/flagable.rb +62 -0
- data/app/models/geo_location.rb +92 -0
- data/app/models/group.rb +224 -0
- data/app/models/group_mixins/corporations.rb +141 -0
- data/app/models/group_mixins/developers.rb +41 -0
- data/app/models/group_mixins/everyone.rb +72 -0
- data/app/models/group_mixins/guests.rb +61 -0
- data/app/models/group_mixins/hidden_users.rb +43 -0
- data/app/models/group_mixins/import.rb +321 -0
- data/app/models/group_mixins/memberships.rb +207 -0
- data/app/models/group_mixins/officers.rb +47 -0
- data/app/models/group_mixins/roles.rb +41 -0
- data/app/models/horizontal_nav.rb +32 -0
- data/app/models/last_seen_activity.rb +10 -0
- data/app/models/list_export.rb +359 -0
- data/app/models/may_need_review.rb +54 -0
- data/app/models/metric_logger.rb +83 -0
- data/app/models/nav_node.rb +169 -0
- data/app/models/navable.rb +46 -0
- data/app/models/object_to_b_extension.rb +12 -0
- data/app/models/page.rb +212 -0
- data/app/models/password.rb +28 -0
- data/app/models/post.rb +199 -0
- data/app/models/profile.rb +36 -0
- data/app/models/profile_field.rb +196 -0
- data/app/models/profile_field_mixins/has_child_profile_fields.rb +114 -0
- data/app/models/profile_field_types/about.rb +9 -0
- data/app/models/profile_field_types/academic_degree.rb +10 -0
- data/app/models/profile_field_types/address.rb +88 -0
- data/app/models/profile_field_types/bank_account.rb +12 -0
- data/app/models/profile_field_types/competence.rb +7 -0
- data/app/models/profile_field_types/custom.rb +12 -0
- data/app/models/profile_field_types/date.rb +14 -0
- data/app/models/profile_field_types/description.rb +15 -0
- data/app/models/profile_field_types/email.rb +20 -0
- data/app/models/profile_field_types/employment.rb +24 -0
- data/app/models/profile_field_types/general.rb +9 -0
- data/app/models/profile_field_types/homepage.rb +19 -0
- data/app/models/profile_field_types/name_surrounding.rb +11 -0
- data/app/models/profile_field_types/organization.rb +24 -0
- data/app/models/profile_field_types/phone.rb +37 -0
- data/app/models/profile_field_types/professional_category.rb +8 -0
- data/app/models/profile_field_types/study.rb +18 -0
- data/app/models/profile_section.rb +49 -0
- data/app/models/profileable.rb +58 -0
- data/app/models/profileable_mixins/address.rb +118 -0
- data/app/models/relationship.rb +78 -0
- data/app/models/role.rb +164 -0
- data/app/models/setting.rb +9 -0
- data/app/models/status_group.rb +28 -0
- data/app/models/status_group_membership.rb +189 -0
- data/app/models/status_group_membership_info.rb +54 -0
- data/app/models/structureable.rb +164 -0
- data/app/models/structureable_mixins/has_special_groups.rb +127 -0
- data/app/models/structureable_mixins/roles.rb +275 -0
- data/app/models/user.rb +878 -0
- data/app/models/user_account.rb +162 -0
- data/app/models/user_alias.rb +112 -0
- data/app/models/user_group_membership.rb +300 -0
- data/app/models/user_group_membership_mixins/validity_range.rb +206 -0
- data/app/models/user_group_membership_mixins/validity_range_for_indirect_memberships.rb +160 -0
- data/app/models/user_mixins/identification.rb +36 -0
- data/app/models/user_mixins/memberships.rb +75 -0
- data/app/models/workflow.rb +40 -0
- data/app/models/workflow_kit/add_to_group_brick.rb +21 -0
- data/app/models/workflow_kit/destroy_account_and_end_memberships_if_needed_brick.rb +19 -0
- data/app/models/workflow_kit/last_membership_needs_review_brick.rb +19 -0
- data/app/models/workflow_kit/mark_as_deceased_brick.rb +17 -0
- data/app/models/workflow_kit/remove_from_group_brick.rb +27 -0
- data/app/models/workflow_kit/test_brick.rb +13 -0
- data/app/pdfs/address_labels_pdf.rb +157 -0
- data/app/presenters/base_presenter.rb +52 -0
- data/app/presenters/horizontal_nav_presenter.rb +106 -0
- data/app/uploaders/attachment_uploader.rb +148 -0
- data/app/views/activities/index.html.haml +25 -0
- data/app/views/attachments/_attachment.html.haml +20 -0
- data/app/views/attachments/_description.html.haml +11 -0
- data/app/views/attachments/_documents.html.haml +17 -0
- data/app/views/attachments/_drop_field.html.haml +46 -0
- data/app/views/attachments/_picture.html.haml +2 -0
- data/app/views/attachments/_pictures.html.haml +10 -0
- data/app/views/attachments/_video.html.haml +8 -0
- data/app/views/attachments/create.js.erb +1 -0
- data/app/views/attachments/destroy.js.erb +1 -0
- data/app/views/blog_posts/create.js.erb +17 -0
- data/app/views/bookmarks/_list.html.haml +7 -0
- data/app/views/bookmarks/update.js.erb +4 -0
- data/app/views/devise/mailer/reset_password_instructions.html.haml +8 -0
- data/app/views/devise/passwords/edit.html.haml +1 -0
- data/app/views/devise/passwords/new.html.haml +12 -0
- data/app/views/devise/registrations/edit.html.haml +1 -0
- data/app/views/devise/sessions/new.html.haml +14 -0
- data/app/views/devise/shared/_links.haml +26 -0
- data/app/views/errors/show.html.haml +5 -0
- data/app/views/errors/unauthorized.html.haml +7 -0
- data/app/views/event_mailer/invitation_email.html.erb +63 -0
- data/app/views/events/_event_details.html.haml +54 -0
- data/app/views/events/_events_lis.html.haml +29 -0
- data/app/views/events/_invitation_text.html.erb +8 -0
- data/app/views/events/_pictures.html.haml +5 -0
- data/app/views/events/_public_index.html.haml +16 -0
- data/app/views/events/index.html.haml +24 -0
- data/app/views/events/show.html.haml +50 -0
- data/app/views/groups/_address_labels_modal.html.haml +27 -0
- data/app/views/groups/_export_button.html.haml +66 -0
- data/app/views/groups/_group_list.html.haml +25 -0
- data/app/views/groups/_member_avatars.html.haml +4 -0
- data/app/views/groups/_member_list.html.haml +15 -0
- data/app/views/groups/index.html.erb +11 -0
- data/app/views/groups/index_mine.html.haml +7 -0
- data/app/views/groups/show.html.haml +79 -0
- data/app/views/last_seen_activities/_index.html.haml +19 -0
- data/app/views/layouts/_add_structureable_additions.html.haml +15 -0
- data/app/views/layouts/_box.html.haml +16 -0
- data/app/views/layouts/_help_button.html.haml +1 -0
- data/app/views/layouts/_role_preview_switcher.html.haml +20 -0
- data/app/views/layouts/_session_bar_avatar.html.haml +1 -0
- data/app/views/layouts/_vertical_nav.html.haml +5 -0
- data/app/views/layouts/bootstrap.html.haml +146 -0
- data/app/views/layouts/mercury.html.erb +23 -0
- data/app/views/officers/_history_notice.html.haml +4 -0
- data/app/views/officers/_officers_box.html.haml +33 -0
- data/app/views/officers/_officers_group_entry.html.haml +45 -0
- data/app/views/pages/_attachments.html.haml +21 -0
- data/app/views/pages/_page.html.haml +28 -0
- data/app/views/pages/_pictures.html.haml +2 -0
- data/app/views/pages/_videos.html.erb +8 -0
- data/app/views/pages/show.html.haml +39 -0
- data/app/views/post_mailer/post_email.html.erb +17 -0
- data/app/views/posts/_new_post_template_text.html.haml +6 -0
- data/app/views/posts/_post.html.haml +13 -0
- data/app/views/posts/_post_quote.html.haml +18 -0
- data/app/views/posts/_posts.html.haml +6 -0
- data/app/views/posts/index.html.haml +9 -0
- data/app/views/posts/new.html.haml +42 -0
- data/app/views/posts/show.html.haml +8 -0
- data/app/views/profile_fields/_postal_address_flag_switch.html.haml +21 -0
- data/app/views/profile_fields/_profile_field.html.haml +41 -0
- data/app/views/profile_fields/create.js.erb +26 -0
- data/app/views/profile_fields/destroy.js.erb +3 -0
- data/app/views/profiles/_add_profile_field_button.html.haml +15 -0
- data/app/views/profiles/_profile_section_ul.html.haml +8 -0
- data/app/views/profiles/_section.html.haml +28 -0
- data/app/views/profiles/_send_group_message_button.html.haml +4 -0
- data/app/views/root/_latest_members_box.html.haml +19 -0
- data/app/views/root/_start_page_elements.html.haml +0 -0
- data/app/views/root/_what_is_new.html.haml +21 -0
- data/app/views/search/_preview_blog_post.html.haml +1 -0
- data/app/views/search/_preview_corporation.html.haml +5 -0
- data/app/views/search/_preview_group.html.haml +4 -0
- data/app/views/search/_preview_page.html.haml +11 -0
- data/app/views/search/_preview_user.html.haml +14 -0
- data/app/views/search/index.html.haml +42 -0
- data/app/views/setup/index.html.haml +56 -0
- data/app/views/shared/_add_structureable.html.haml +22 -0
- data/app/views/shared/_authorization_info.html.haml +22 -0
- data/app/views/shared/_flags.html.haml +5 -0
- data/app/views/shared/_markdown_help.html.haml +4 -0
- data/app/views/shared/_search_box.html.haml +2 -0
- data/app/views/shared/_upcoming_events.html.haml +33 -0
- data/app/views/statistics/index.html.haml +16 -0
- data/app/views/statistics/show.html.haml +13 -0
- data/app/views/terms_of_use/_checkbox.html.haml +1 -0
- data/app/views/terms_of_use/_terms.html.haml +1 -0
- data/app/views/terms_of_use/index.html.haml +19 -0
- data/app/views/user_account_mailer/welcome_email.html.erb +32 -0
- data/app/views/user_accounts/_change_password.html.haml +149 -0
- data/app/views/user_accounts/_user_account.html.haml +39 -0
- data/app/views/user_group_memberships/_list_item.html.haml +9 -0
- data/app/views/user_group_memberships/_memberships_table.html.haml +56 -0
- data/app/views/user_group_memberships/_new.html.haml +18 -0
- data/app/views/user_group_memberships/create.js.erb +9 -0
- data/app/views/user_group_memberships/index.html.haml +5 -0
- data/app/views/user_settings/show.html.haml +36 -0
- data/app/views/users/_avatar.html.haml +16 -0
- data/app/views/users/_communication_box.html.haml +8 -0
- data/app/views/users/_corporate_vita.html.haml +23 -0
- data/app/views/users/_dead_badge.html.haml +3 -0
- data/app/views/users/_deceased_modal.html.haml +24 -0
- data/app/views/users/_hidden_badge.html.haml +4 -0
- data/app/views/users/_hidden_flag_switch.html.haml +20 -0
- data/app/views/users/_special_general_info_fields.html.haml +10 -0
- data/app/views/users/_user_corporation_attribute.html.haml +6 -0
- data/app/views/users/_user_name_attribute.html.haml +4 -0
- data/app/views/users/_user_title.html.haml +5 -0
- data/app/views/users/_workflow_triggers.html.haml +23 -0
- data/app/views/users/new.html.haml +55 -0
- data/app/views/users/show.html.haml +79 -0
- data/config/environment.rb +5 -0
- data/config/initializers/active_record_cache_extension.rb +1 -0
- data/config/initializers/active_record_find_by_extension.rb +1 -0
- data/config/initializers/active_record_flagable_extension.rb +2 -0
- data/config/initializers/active_record_json_url_extension.rb +1 -0
- data/config/initializers/active_record_may_need_review_extension.rb +2 -0
- data/config/initializers/active_record_metric_events_extension.rb +1 -0
- data/config/initializers/active_record_navable_extension.rb +6 -0
- data/config/initializers/active_record_profileable_extension.rb +4 -0
- data/config/initializers/active_record_read_only_extension.rb +1 -0
- data/config/initializers/active_record_structureable_extension.rb +3 -0
- data/config/initializers/active_record_update_attributes_bip_extension.rb +1 -0
- data/config/initializers/array_extension.rb +1 -0
- data/config/initializers/best_in_place_display_definitions.rb +31 -0
- data/config/initializers/cache_store_extension.rb +1 -0
- data/config/initializers/devise.rb +240 -0
- data/config/initializers/fnordmetric.rb +14 -0
- data/config/initializers/formtastic.rb +76 -0
- data/config/initializers/group_type_column_patches.rb +11 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/mini_profiler.rb +32 -0
- data/config/initializers/object_to_b_extension.rb +1 -0
- data/config/initializers/refile.rb +22 -0
- data/config/initializers/sidekiq.rb +12 -0
- data/config/locales/attachments/de.yml +33 -0
- data/config/locales/bookmarks/de.yml +3 -0
- data/config/locales/bookmarks/en.yml +3 -0
- data/config/locales/common_expressions/de.yml +5 -0
- data/config/locales/common_expressions/en.yml +5 -0
- data/config/locales/companies/de.yml +4 -0
- data/config/locales/companies/en.yml +4 -0
- data/config/locales/de.yml +30 -0
- data/config/locales/devise/de.yml +60 -0
- data/config/locales/devise/en.yml +62 -0
- data/config/locales/en.yml +25 -0
- data/config/locales/events/de.yml +34 -0
- data/config/locales/events/en.yml +34 -0
- data/config/locales/forms/de.yml +3 -0
- data/config/locales/groups/de.yml +56 -0
- data/config/locales/groups/en.yml +47 -0
- data/config/locales/officers/de.yml +10 -0
- data/config/locales/pages/de.yml +15 -0
- data/config/locales/pages/en.yml +14 -0
- data/config/locales/pagination/de.yml +6 -0
- data/config/locales/pagination/en.yml +5 -0
- data/config/locales/password_strength/de.yml +9 -0
- data/config/locales/password_strength/en.yml +9 -0
- data/config/locales/posts/de.yml +9 -0
- data/config/locales/profile_fields/de.yml +78 -0
- data/config/locales/profile_fields/en.yml +22 -0
- data/config/locales/profiles/de.yml +47 -0
- data/config/locales/profiles/en.yml +44 -0
- data/config/locales/roles/de.yml +9 -0
- data/config/locales/root/de.yml +3 -0
- data/config/locales/root/en.yml +3 -0
- data/config/locales/search/de.yml +11 -0
- data/config/locales/search/en.yml +11 -0
- data/config/locales/sessions/de.yml +37 -0
- data/config/locales/sessions/en.yml +37 -0
- data/config/locales/setup/de.yml +26 -0
- data/config/locales/setup/en.yml +26 -0
- data/config/locales/statistics/de.yml +6 -0
- data/config/locales/terms_of_use/de.yml +6 -0
- data/config/locales/tools/de.yml +9 -0
- data/config/locales/tools/en.yml +9 -0
- data/config/locales/user_accounts/de.yml +16 -0
- data/config/locales/user_accounts/en.yml +13 -0
- data/config/locales/user_settings/de.yml +9 -0
- data/config/locales/users/de.yml +82 -0
- data/config/locales/users/en.yml +51 -0
- data/config/locales/workflows/de.yml +4 -0
- data/config/locales/workflows/en.yml +4 -0
- data/config/routes.rb +104 -0
- data/db/migrate/20120403002734_create_users.rb +12 -0
- data/db/migrate/20120403011601_create_profile_fields.rb +11 -0
- data/db/migrate/20120403161549_remove_user_email_column.rb +5 -0
- data/db/migrate/20120405222050_encrypt_password.rb +8 -0
- data/db/migrate/20120425161138_create_dag_links.rb +14 -0
- data/db/migrate/20120425162644_create_pages.rb +10 -0
- data/db/migrate/20120426023322_create_groups.rb +9 -0
- data/db/migrate/20120426090436_create_nav_nodes.rb +18 -0
- data/db/migrate/20120427021934_create_user_accounts.rb +12 -0
- data/db/migrate/20120427044338_add_foreign_key_to_user_accounts.rb +7 -0
- data/db/migrate/20120427150156_add_group_token.rb +8 -0
- data/db/migrate/20120507165551_make_profile_fields_polymorphic.rb +11 -0
- data/db/migrate/20120508130729_add_profile_field_acts_as_tree.rb +9 -0
- data/db/migrate/20120508152233_change_profile_field_value_to_text.rb +9 -0
- data/db/migrate/20120508201550_add_group_internal_token.rb +11 -0
- data/db/migrate/20120511090234_create_workflows.rb +9 -0
- data/db/migrate/20120701115059_add_password_digest_to_user_accounts.rb +5 -0
- data/db/migrate/20120710193308_remove_salt_from_user_accounts.rb +5 -0
- data/db/migrate/20120713102445_add_deleted_at_to_dag_links.rb +5 -0
- data/db/migrate/20120722005022_create_workflow_kit_workflows.workflow_kit.rb +11 -0
- data/db/migrate/20120722005023_create_workflow_kit_steps.workflow_kit.rb +12 -0
- data/db/migrate/20120722005024_create_workflow_kit_parameters.workflow_kit.rb +12 -0
- data/db/migrate/20120723165226_add_female_to_users.rb +5 -0
- data/db/migrate/20120811140509_create_flags.rb +11 -0
- data/db/migrate/20120814100529_create_attachments.rb +13 -0
- data/db/migrate/20120815205610_add_content_type_and_file_size_to_attachments.rb +6 -0
- data/db/migrate/20130118220014_add_relationships_table_without_dag.rb +10 -0
- data/db/migrate/20130207214331_create_events.rb +12 -0
- data/db/migrate/20130208215253_create_status_group_membership_infos.rb +11 -0
- data/db/migrate/20130220184943_create_stars.rb +11 -0
- data/db/migrate/20130309193623_add_devise_to_user_accounts.rb +72 -0
- data/db/migrate/20130310003840_rename_stars_to_bookmarks.rb +9 -0
- data/db/migrate/20130310004622_fix_column_names_for_bookmarks.rb +6 -0
- data/db/migrate/20130313211414_create_geo_infos.rb +13 -0
- data/db/migrate/20130313234131_create_geo_locations.rb +16 -0
- data/db/migrate/20130314011638_drop_geo_infos.rb +5 -0
- data/db/migrate/20130315072759_add_invalid_to_geo_location.rb +5 -0
- data/db/migrate/20130315073149_exchange_invalid_for_queried_at_in_geo_location.rb +8 -0
- data/db/migrate/20130320003051_add_redirect_to_to_page.rb +5 -0
- data/db/migrate/20130329231657_create_posts.rb +15 -0
- data/db/migrate/20130404223735_add_entire_message_to_posts.rb +5 -0
- data/db/migrate/20130409192959_add_author_to_page.rb +5 -0
- data/db/migrate/20130908011215_add_type_to_pages.rb +5 -0
- data/db/migrate/20131115114715_validity_range_for_dag_links.rb +16 -0
- data/db/migrate/20140611170430_create_activities.rb +23 -0
- data/db/migrate/20140808223512_create_last_seen_activities.rb +12 -0
- data/db/migrate/20141008101744_add_location_to_events.rb +5 -0
- data/db/migrate/20141010130344_add_publish_on_website_to_events.rb +6 -0
- data/db/migrate/20141010134227_add_auth_token_to_user_accounts.rb +5 -0
- data/db/migrate/20141018143323_add_accepted_terms_to_users.rb +6 -0
- data/db/migrate/20141018221659_add_author_to_attachments.rb +5 -0
- data/db/migrate/20141102223954_add_body_to_groups.rb +5 -0
- data/db/migrate/20141110193830_create_settings.rb +17 -0
- data/db/migrate/20141202140522_add_indices.rb +6 -0
- data/db/migrate/20141209161946_add_keys.rb +20 -0
- data/db/migrate/20150127013809_add_incognito_to_users.rb +5 -0
- data/db/migrate/20150129194501_add_indices_for_polymorphic_references.rb +13 -0
- data/db/migrate/20150304192448_add_type_to_groups.rb +5 -0
- data/db/migrate/20150313221004_add_avatar_id_to_users.rb +5 -0
- data/lib/best_in_place/controller_extensions.rb +25 -0
- data/lib/best_in_place/helper.rb +127 -0
- data/lib/tasks/db_bootstrap.rake +37 -0
- data/lib/tasks/your_platform_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +11 -0
- data/lib/your_platform.rb +6 -2
- data/lib/your_platform/engine.rb +127 -0
- data/lib/your_platform/version.rb +1 -1
- data/spec/factories/attachment.rb +12 -0
- data/spec/factories/blog_post.rb +10 -0
- data/spec/factories/company.rb +7 -0
- data/spec/factories/corporation.rb +20 -0
- data/spec/factories/event.rb +13 -0
- data/spec/factories/group.rb +36 -0
- data/spec/factories/html_email.eml +1059 -0
- data/spec/factories/mail_message.rb +30 -0
- data/spec/factories/page.rb +10 -0
- data/spec/factories/relationship.rb +13 -0
- data/spec/factories/status_group_membership.rb +21 -0
- data/spec/factories/user.rb +97 -0
- data/spec/factories/workflow.rb +44 -0
- data/spec/features/blog_post_spec.rb +46 -0
- data/spec/features/corporate_vita_events_spec.rb +114 -0
- data/spec/features/corporate_vita_spec.rb +258 -0
- data/spec/features/edit_mode_after_clicking_a_link_spec.rb +20 -0
- data/spec/features/events_spec.rb +356 -0
- data/spec/features/group_export_spec.rb +19 -0
- data/spec/features/group_post_spec.rb +89 -0
- data/spec/features/groups_of_groups_page_spec.rb +67 -0
- data/spec/features/groups_page_spec.rb +66 -0
- data/spec/features/groups_table_spec.rb +32 -0
- data/spec/features/help_page_spec.rb +22 -0
- data/spec/features/intranet_root_page_spec.rb +18 -0
- data/spec/features/locales_spec.rb +36 -0
- data/spec/features/maps_spec.rb +53 -0
- data/spec/features/mini_profiler_spec.rb +37 -0
- data/spec/features/officers_spec.rb +61 -0
- data/spec/features/page_redirects_spec.rb +23 -0
- data/spec/features/page_spec.rb +20 -0
- data/spec/features/postal_address_flag_spec.rb +46 -0
- data/spec/features/relationships_on_user_page_spec.rb +78 -0
- data/spec/features/review_membership_spec.rb +44 -0
- data/spec/features/search_field_spec.rb +121 -0
- data/spec/features/setup_spec.rb +63 -0
- data/spec/features/user_change_date_of_birth_spec.rb +26 -0
- data/spec/features/vertical_nav_spec.rb +27 -0
- data/spec/features/what_is_new_box_spec.rb +33 -0
- data/spec/helpers/attachments_helper_spec.rb +15 -0
- data/spec/models/ability_spec.rb +93 -0
- data/spec/models/active_record_cache_extension_spec.rb +177 -0
- data/spec/models/active_record_find_by_extension_spec.rb +26 -0
- data/spec/models/active_record_json_url_extension_spec.rb +79 -0
- data/spec/models/address_label_spec.rb +144 -0
- data/spec/models/app_version_spec.rb +38 -0
- data/spec/models/attachment_spec.rb +5 -0
- data/spec/models/bookmark_spec.rb +70 -0
- data/spec/models/concerns/user_corporations_spec.rb +71 -0
- data/spec/models/corporation_spec.rb +128 -0
- data/spec/models/dag_link_spec.rb +48 -0
- data/spec/models/event_spec.rb +267 -0
- data/spec/models/flag_spec.rb +20 -0
- data/spec/models/flagable_spec.rb +55 -0
- data/spec/models/geo_location_spec.rb +126 -0
- data/spec/models/group_mixins/corporations_spec.rb +95 -0
- data/spec/models/group_mixins/everyone_spec.rb +64 -0
- data/spec/models/group_mixins/guests_spec.rb +75 -0
- data/spec/models/group_mixins/hidden_users_spec.rb +21 -0
- data/spec/models/group_mixins/import_spec.rb +93 -0
- data/spec/models/group_mixins/memberships_spec.rb +303 -0
- data/spec/models/group_mixins/officers_spec.rb +63 -0
- data/spec/models/group_mixins/roles_spec.rb +46 -0
- data/spec/models/group_spec.rb +341 -0
- data/spec/models/list_export_spec.rb +155 -0
- data/spec/models/may_need_review_spec.rb +114 -0
- data/spec/models/nav_node_spec.rb +277 -0
- data/spec/models/navable_spec.rb +54 -0
- data/spec/models/page_spec.rb +185 -0
- data/spec/models/post_spec.rb +271 -0
- data/spec/models/profile_field_mixins/has_child_profile_fields_spec.rb +73 -0
- data/spec/models/profile_field_spec.rb +482 -0
- data/spec/models/profile_section_spec.rb +89 -0
- data/spec/models/profile_spec.rb +74 -0
- data/spec/models/profileable_mixins/adress_spec.rb +93 -0
- data/spec/models/profileable_spec.rb +152 -0
- data/spec/models/relationship_spec.rb +113 -0
- data/spec/models/status_group_membership_spec.rb +350 -0
- data/spec/models/status_group_spec.rb +103 -0
- data/spec/models/structureable_mixins/has_special_groups_spec.rb +479 -0
- data/spec/models/structureable_mixins/roles_spec.rb +517 -0
- data/spec/models/structureable_spec.rb +128 -0
- data/spec/models/user_account_spec.rb +142 -0
- data/spec/models/user_alias_spec.rb +57 -0
- data/spec/models/user_group_membership_mixins/validity_range_for_indirect_memberships_spec.rb +291 -0
- data/spec/models/user_group_membership_mixins/validity_range_spec.rb +293 -0
- data/spec/models/user_group_membership_spec.rb +428 -0
- data/spec/models/user_mixins/identification_spec.rb +27 -0
- data/spec/models/user_mixins/memberships_spec.rb +138 -0
- data/spec/models/user_spec.rb +1794 -0
- data/spec/old_yp_spec_helper.rb +46 -0
- data/spec/spec_helper.rb +350 -0
- data/spec/support/auto_complete.rb +22 -0
- data/spec/support/capybara/flash_helpers.rb +37 -0
- data/spec/support/capybara/profile_steps.rb +73 -0
- data/spec/support/capybara/session_steps.rb +53 -0
- data/spec/support/capybara/user_account_helpers.rb +15 -0
- data/spec/support/debug.rb +8 -0
- data/spec/support/devise-controller_macros.rb +15 -0
- data/spec/support/geocoder/stubs.rb +60 -0
- data/spec/support/press_enter.rb +15 -0
- data/spec/support/time_travel.rb +9 -0
- data/spec/support/uploads/image-upload.png +0 -0
- data/spec/support/uploads/pdf-upload.pdf +0 -0
- data/spec/support/wait_for_ajax.rb +39 -0
- data/spec/support/wait_for_cache.rb +7 -0
- data/spec/uploaders/attachment_uploader_spec.rb +47 -0
- data/vendor/assets/images/flags.png +0 -0
- data/vendor/assets/images/galleria/classic-loader.gif +0 -0
- data/vendor/assets/images/galleria/classic-map.png +0 -0
- data/vendor/assets/javascripts/best_in_place_datetime.js.coffee +45 -0
- data/vendor/assets/javascripts/galleria-classic.js +100 -0
- data/vendor/assets/javascripts/galleria.js +6919 -0
- data/vendor/assets/javascripts/gmaps4rails.js +2 -0
- data/vendor/assets/javascripts/gmaps4rails/all.js +1 -0
- data/vendor/assets/javascripts/gmaps4rails/base.coffee +1 -0
- data/vendor/assets/javascripts/gmaps4rails/base/common.coffee +43 -0
- data/vendor/assets/javascripts/gmaps4rails/base/configuration.coffee +7 -0
- data/vendor/assets/javascripts/gmaps4rails/base/gmaps.coffee +13 -0
- data/vendor/assets/javascripts/gmaps4rails/base/interfaces/basic_interface.coffee +15 -0
- data/vendor/assets/javascripts/gmaps4rails/base/interfaces/controller_interface.coffee +15 -0
- data/vendor/assets/javascripts/gmaps4rails/base/interfaces/map_interface.coffee +27 -0
- data/vendor/assets/javascripts/gmaps4rails/base/interfaces/marker_interface.coffee +15 -0
- data/vendor/assets/javascripts/gmaps4rails/base/main.coffee +124 -0
- data/vendor/assets/javascripts/gmaps4rails/base/main_controller_extensions/circle_controller.coffee +29 -0
- data/vendor/assets/javascripts/gmaps4rails/base/main_controller_extensions/kml_controller.coffee +5 -0
- data/vendor/assets/javascripts/gmaps4rails/base/main_controller_extensions/marker_controller.coffee +76 -0
- data/vendor/assets/javascripts/gmaps4rails/base/main_controller_extensions/polygon_controller.coffee +29 -0
- data/vendor/assets/javascripts/gmaps4rails/base/main_controller_extensions/polyline_controller.coffee +29 -0
- data/vendor/assets/javascripts/gmaps4rails/base/objects/circle.coffee +12 -0
- data/vendor/assets/javascripts/gmaps4rails/base/objects/kml.coffee +8 -0
- data/vendor/assets/javascripts/gmaps4rails/base/objects/map.coffee +62 -0
- data/vendor/assets/javascripts/gmaps4rails/base/objects/marker.coffee +24 -0
- data/vendor/assets/javascripts/gmaps4rails/base/objects/polygon.coffee +11 -0
- data/vendor/assets/javascripts/gmaps4rails/base/objects/polyline.coffee +11 -0
- data/vendor/assets/javascripts/gmaps4rails/bing.coffee +1 -0
- data/vendor/assets/javascripts/gmaps4rails/bing/main.coffee +29 -0
- data/vendor/assets/javascripts/gmaps4rails/bing/objects/map.coffee +63 -0
- data/vendor/assets/javascripts/gmaps4rails/bing/objects/marker.coffee +78 -0
- data/vendor/assets/javascripts/gmaps4rails/bing/shared.coffee +20 -0
- data/vendor/assets/javascripts/gmaps4rails/google.coffee +1 -0
- data/vendor/assets/javascripts/gmaps4rails/google/main.coffee +47 -0
- data/vendor/assets/javascripts/gmaps4rails/google/objects/circle.coffee +38 -0
- data/vendor/assets/javascripts/gmaps4rails/google/objects/kml.coffee +16 -0
- data/vendor/assets/javascripts/gmaps4rails/google/objects/map.coffee +71 -0
- data/vendor/assets/javascripts/gmaps4rails/google/objects/marker.coffee +114 -0
- data/vendor/assets/javascripts/gmaps4rails/google/objects/polygon.coffee +38 -0
- data/vendor/assets/javascripts/gmaps4rails/google/objects/polyline.coffee +49 -0
- data/vendor/assets/javascripts/gmaps4rails/google/shared.coffee +27 -0
- data/vendor/assets/javascripts/gmaps4rails/openlayers.coffee +1 -0
- data/vendor/assets/javascripts/gmaps4rails/openlayers/main.coffee +138 -0
- data/vendor/assets/javascripts/gmaps4rails/openlayers/objects/map.coffee +49 -0
- data/vendor/assets/javascripts/gmaps4rails/openlayers/objects/marker.coffee +68 -0
- data/vendor/assets/javascripts/gmaps4rails/openlayers/objects/polyline.coffee +39 -0
- data/vendor/assets/javascripts/gmaps4rails/openlayers/shared.coffee +19 -0
- data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +2223 -0
- data/vendor/assets/javascripts/jquery-ui-timepicker-de.js +26 -0
- data/vendor/assets/javascripts/jquery.ui.datepicker-de.js +23 -0
- data/vendor/assets/javascripts/password_strength.js +149 -0
- data/vendor/assets/javascripts/zxcvbn.js +43 -0
- data/vendor/assets/stylesheets/flags.css.scss +259 -0
- data/vendor/assets/stylesheets/galleria-classic.css.scss +239 -0
- data/vendor/assets/stylesheets/gmaps4rails.css +24 -0
- data/vendor/assets/stylesheets/mercury.css +24 -0
- data/vendor/scripts/bashpass/README.md +29 -0
- data/vendor/scripts/bashpass/bashpass +124 -0
- data/vendor/scripts/bashpass/bashpass-APACHE-LICENSE +201 -0
- data/vendor/scripts/bashpass/german.dic +40794 -0
- metadata +1540 -16
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -4
- data/your_platform.gemspec +0 -19
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Every User may have an UserAccount that enables the user to log in to the website.
|
|
3
|
+
#
|
|
4
|
+
# user = User.create(...) # This user may not log in.
|
|
5
|
+
# account = user.build_account
|
|
6
|
+
# account.password = "foo"
|
|
7
|
+
# account.save # Now, the user may log in.
|
|
8
|
+
# account.destroy # Now, the user may not log in anymore.
|
|
9
|
+
#
|
|
10
|
+
class UserAccount < ActiveRecord::Base
|
|
11
|
+
|
|
12
|
+
# For authentication, we use devise,
|
|
13
|
+
# https://github.com/plataformatec/devise.
|
|
14
|
+
#
|
|
15
|
+
# Available Modules:
|
|
16
|
+
# Database Authenticatable:
|
|
17
|
+
# encrypts and stores a password in the database to validate the authenticity of a user
|
|
18
|
+
# while signing in. The authentication can be done both through POST requests or
|
|
19
|
+
# HTTP Basic Authentication.
|
|
20
|
+
# Omniauthable: adds Omniauth (https://github.com/intridea/omniauth) support;
|
|
21
|
+
# Confirmable: sends emails with confirmation instructions and verifies whether an account
|
|
22
|
+
# is already confirmed during sign in.
|
|
23
|
+
# Recoverable: resets the user password and sends reset instructions.
|
|
24
|
+
# Registerable: handles signing up users through a registration process, also allowing
|
|
25
|
+
# them to edit and destroy their account.
|
|
26
|
+
# Rememberable: manages generating and clearing a token for remembering the user from a
|
|
27
|
+
# saved cookie.
|
|
28
|
+
# Trackable: tracks sign in count, timestamps and IP address.
|
|
29
|
+
# Timeoutable: expires sessions that have no activity in a specified period of time.
|
|
30
|
+
# Validatable: provides validations of email and password. It's optional and can be customized,
|
|
31
|
+
# so you're able to define your own validations.
|
|
32
|
+
# Lockable: locks an account after a specified number of failed sign-in attempts.
|
|
33
|
+
# Can unlock via email or after a specified time period.
|
|
34
|
+
#
|
|
35
|
+
devise :database_authenticatable, :recoverable, :rememberable, :validatable, :registerable
|
|
36
|
+
attr_accessible :password, :password_confirmation, :remember_me
|
|
37
|
+
|
|
38
|
+
# Virtual attribute for authenticating by either username, alias or email
|
|
39
|
+
attr_accessor :login
|
|
40
|
+
|
|
41
|
+
belongs_to :user, inverse_of: :account
|
|
42
|
+
|
|
43
|
+
before_validation :generate_password_if_unset
|
|
44
|
+
# This needs to run before validation, since validation
|
|
45
|
+
# requires a password to be set in order to allow saving the account.
|
|
46
|
+
# See ressources of `has_secure_password` above.
|
|
47
|
+
|
|
48
|
+
before_save :generate_password_if_unset
|
|
49
|
+
# This is required, because, apparently, the `before_validation` callback is not called
|
|
50
|
+
# if the account is created via an association (like User.create( ... , create_account: true )).
|
|
51
|
+
# But `before_save` callbacks are called.
|
|
52
|
+
# Notice: Apparently, even `validates_associated :account` in the User model has no effect.
|
|
53
|
+
|
|
54
|
+
delegate :email, :to => :user, :allow_nil => true
|
|
55
|
+
|
|
56
|
+
def readonly?
|
|
57
|
+
false # Otherwise, the user is not able to login.
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# HACK: This method seems to be required by the PasswordController and is missing,
|
|
61
|
+
# since we have a virtual email field.
|
|
62
|
+
# TODO: If we ever change the Password authentication
|
|
63
|
+
def email= value
|
|
64
|
+
#dummy required by devise to create an 'error' user account
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def email_changed?
|
|
68
|
+
false
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Configure each account to *not* automatically log out when the browser is closed.
|
|
72
|
+
# After a system reboot, the user is still logged in, which is the expected behaviour
|
|
73
|
+
# for this application.
|
|
74
|
+
#
|
|
75
|
+
# This useses devise's rememberable module.
|
|
76
|
+
#
|
|
77
|
+
def remember_me
|
|
78
|
+
true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Used by devise to identify the correct user account by the given strings.
|
|
82
|
+
#
|
|
83
|
+
def self.find_first_by_auth_conditions(warden_conditions)
|
|
84
|
+
login_string = warden_conditions[:login] || warden_conditions[:email]
|
|
85
|
+
return UserAccount.identify(login_string) if login_string
|
|
86
|
+
return UserAccount.where(warden_conditions).first # use devise identification system for auth tokens and the like.
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Tries to identify a user based on the given `login_string`.
|
|
90
|
+
# This can be one of those defined in `User.attributes_used_for_identification`,
|
|
91
|
+
# currently, `[:alias, :last_name, :name, :email]`.
|
|
92
|
+
#
|
|
93
|
+
# Bug fix: The alias is prioritized, such that a user having the alias *doe*
|
|
94
|
+
# can be identified by this alias even if there are other users with surname *Doe*.
|
|
95
|
+
#
|
|
96
|
+
def self.identify(login_string)
|
|
97
|
+
|
|
98
|
+
# Priorization: Check alias first. (Bug fix)
|
|
99
|
+
user_identified_by_alias = User.find_by_alias(login_string)
|
|
100
|
+
users_that_match_the_login_string = [ User.find_by_alias(login_string) ] if user_identified_by_alias
|
|
101
|
+
|
|
102
|
+
# What can go wrong?
|
|
103
|
+
# 1. No user could match the login string.
|
|
104
|
+
users_that_match_the_login_string ||= User.find_all_by_identification_string( login_string )
|
|
105
|
+
#raise 'no_user_found' unless users_that_match_the_login_string.count > 0
|
|
106
|
+
return nil unless users_that_match_the_login_string.count > 0
|
|
107
|
+
|
|
108
|
+
# 2. The user may not have an active user account.
|
|
109
|
+
users_that_match_the_login_string_and_have_an_account = users_that_match_the_login_string.select do |user|
|
|
110
|
+
user.has_account?
|
|
111
|
+
end
|
|
112
|
+
raise 'user_has_no_account' unless users_that_match_the_login_string_and_have_an_account.count > 0
|
|
113
|
+
|
|
114
|
+
# 3. The identification string may refer to several users with an active user account.
|
|
115
|
+
raise 'identification_not_unique' if users_that_match_the_login_string_and_have_an_account.count > 1
|
|
116
|
+
identified_user = users_that_match_the_login_string_and_have_an_account.first
|
|
117
|
+
|
|
118
|
+
return identified_user.account
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def send_new_password
|
|
122
|
+
generate_password
|
|
123
|
+
self.save
|
|
124
|
+
send_welcome_email
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def generate_password
|
|
128
|
+
self.password = Password.generate
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# This generates a password if (1) no password is stored in the database
|
|
132
|
+
# and (2) no new password is set to be saved (in the `password` attribute).
|
|
133
|
+
def generate_password_if_unset
|
|
134
|
+
if self.encrypted_password.blank?
|
|
135
|
+
unless self.password
|
|
136
|
+
self.generate_password
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def auth_token
|
|
142
|
+
super || generate_auth_token!
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def generate_auth_token!
|
|
146
|
+
# see also: https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
|
|
147
|
+
#
|
|
148
|
+
raise 'auth_token already set' if self.read_attribute(:auth_token)
|
|
149
|
+
token = ''
|
|
150
|
+
loop do
|
|
151
|
+
token = Devise.friendly_token + Devise.friendly_token
|
|
152
|
+
break token unless UserAccount.where(auth_token: token).first
|
|
153
|
+
end
|
|
154
|
+
self.update_attribute :auth_token, token
|
|
155
|
+
token
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def send_welcome_email
|
|
159
|
+
raise 'attempt to send welcome email with empty password' unless self.password
|
|
160
|
+
UserAccountMailer.welcome_email( self.user, self.password ).deliver
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# The UserAlias is a String that is used for identification during login.
|
|
2
|
+
# It can be chosen by the user and defaults to a combination of first and last name.
|
|
3
|
+
# The alias is unique, i.e. two users can't have the same alias.
|
|
4
|
+
#
|
|
5
|
+
# UserAlias.taken?("foo")
|
|
6
|
+
# alias = user.generate_alias
|
|
7
|
+
# alias = UserAlias.generate_for(user)
|
|
8
|
+
#
|
|
9
|
+
class UserAlias < String
|
|
10
|
+
|
|
11
|
+
# UserAlias.taken? "foo" # => false
|
|
12
|
+
# User.create(alias: "foo", ...)
|
|
13
|
+
# UserAlias.taken? "foo" # => <User ...>
|
|
14
|
+
#
|
|
15
|
+
def self.taken?( alias_to_check )
|
|
16
|
+
User.where( :alias => alias_to_check ).try(:first) || false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Checks if the alias is already taken by a User stored in the database.
|
|
20
|
+
#
|
|
21
|
+
# user = User.new(alias: "foo")
|
|
22
|
+
# user.alias.taken? # => false
|
|
23
|
+
# user.save
|
|
24
|
+
# user.alias.taken? # => <User ...>
|
|
25
|
+
#
|
|
26
|
+
def taken?
|
|
27
|
+
UserAlias.taken? self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Generate an alias for a User based on the user's name.
|
|
31
|
+
#
|
|
32
|
+
# user.alias = UserAlias.generate_for(user)
|
|
33
|
+
# user.generate_alias
|
|
34
|
+
#
|
|
35
|
+
def self.generate_for(user)
|
|
36
|
+
raise 'no user given' if not user
|
|
37
|
+
raise 'the given user has no last_name' if not user.last_name.present?
|
|
38
|
+
raise 'the given user has no first_name' if not user.first_name.present?
|
|
39
|
+
|
|
40
|
+
suggestion = try_to_generate_from_last_name(user) # doe
|
|
41
|
+
suggestion ||= try_to_generate_from_first_and_last_name(user) # j.doe
|
|
42
|
+
suggestion ||= try_to_generate_long_from_first_and_last_name(user) # john.doe
|
|
43
|
+
suggestion ||= try_to_generate_long_from_name_and_year_of_birth(user) # john.doe.1986
|
|
44
|
+
|
|
45
|
+
# If the suggestion is still empty (no successful generation), the empty
|
|
46
|
+
# alias will raise a validation error and the user will be asked to enter
|
|
47
|
+
# an alias.
|
|
48
|
+
|
|
49
|
+
return UserAlias.new(suggestion) if suggestion
|
|
50
|
+
return nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# If there is no other user having the same last name, use just the last name
|
|
56
|
+
# as alias.
|
|
57
|
+
#
|
|
58
|
+
def self.try_to_generate_from_last_name(user)
|
|
59
|
+
|
|
60
|
+
# TODO: Rails 4 way: User.where(...).where.not(...)
|
|
61
|
+
# http://stackoverflow.com/questions/5426421/rails-model-find-where-not-equal
|
|
62
|
+
|
|
63
|
+
if User.where("last_name=? AND id!=?", user.last_name, user.id).count == 0
|
|
64
|
+
user.last_name.downcase
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# If there is no other user with the same last name and the same initial of the
|
|
69
|
+
# first name, use a combination like j.doe as alias.
|
|
70
|
+
#
|
|
71
|
+
def self.try_to_generate_from_first_and_last_name(user)
|
|
72
|
+
if User.where("last_name=?
|
|
73
|
+
AND first_name LIKE ?
|
|
74
|
+
AND id!=?",
|
|
75
|
+
user.last_name, "#{user.first_name.first}%", user.id ).count == 0
|
|
76
|
+
"#{user.first_name.downcase.first}.#{user.last_name.downcase}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# If there is no other user with the same first and last name, use
|
|
81
|
+
# a combination like john.doe as alias.
|
|
82
|
+
#
|
|
83
|
+
def self.try_to_generate_long_from_first_and_last_name(user)
|
|
84
|
+
if User.where("last_name=?
|
|
85
|
+
AND first_name=?
|
|
86
|
+
AND id!=?",
|
|
87
|
+
user.last_name, user.first_name, user.id ).count == 0
|
|
88
|
+
"#{user.first_name.downcase}.#{user.last_name.downcase}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# If there is no other user with the same first name, last name and
|
|
93
|
+
# year of birth, use a combination like john.doe.1986 as alias.
|
|
94
|
+
#
|
|
95
|
+
def self.try_to_generate_long_from_name_and_year_of_birth(user)
|
|
96
|
+
if user.date_of_birth
|
|
97
|
+
if User.where("last_name=?
|
|
98
|
+
AND first_name=?
|
|
99
|
+
AND id!=?",
|
|
100
|
+
user.last_name, user.first_name, user.id ).select do |other_user|
|
|
101
|
+
other_user.date_of_birth &&
|
|
102
|
+
(other_user.date_of_birth.year != user.date_of_birth.year)
|
|
103
|
+
end.count == 0
|
|
104
|
+
"#{user.first_name.downcase}.#{user.last_name.downcase}.#{user.date_of_birth.year}"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#
|
|
2
|
+
# In this application, all user group memberships, i.e. memberships of a certain
|
|
3
|
+
# user in a certain group, are stored implicitly in the dag_links table in order
|
|
4
|
+
# to minimize the number of database queries that are necessary to find out
|
|
5
|
+
# whether a user is member in a certain group through an indirect membership.
|
|
6
|
+
#
|
|
7
|
+
# This class allows abstract access to the UserGroupMemberships themselves,
|
|
8
|
+
# and to their properties like since when the membership exists.
|
|
9
|
+
#
|
|
10
|
+
class UserGroupMembership < DagLink
|
|
11
|
+
|
|
12
|
+
before_validation :ensure_correct_ancestor_and_descendant_type
|
|
13
|
+
|
|
14
|
+
# Validity Range
|
|
15
|
+
# ====================================================================================================
|
|
16
|
+
|
|
17
|
+
include UserGroupMembershipMixins::ValidityRange
|
|
18
|
+
include UserGroupMembershipMixins::ValidityRangeForIndirectMemberships
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# May Need Review Flag
|
|
22
|
+
# ====================================================================================================
|
|
23
|
+
|
|
24
|
+
# Some memberships may contain information that need review, e.g. when a validity range
|
|
25
|
+
# was entered by assumption.
|
|
26
|
+
#
|
|
27
|
+
# This is stored as the flag :needs_review.
|
|
28
|
+
#
|
|
29
|
+
has_many_flags
|
|
30
|
+
may_need_review
|
|
31
|
+
attr_accessible :needs_review
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# General Properties
|
|
35
|
+
# ====================================================================================================
|
|
36
|
+
|
|
37
|
+
# Title, e.g. 'Membership of John Doe in GroupXY'
|
|
38
|
+
#
|
|
39
|
+
def title
|
|
40
|
+
I18n.translate( :membership_of_user_in_group, user_name: self.user.title, group_name: self.group.name )
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Creation Class Method
|
|
44
|
+
# ====================================================================================================
|
|
45
|
+
|
|
46
|
+
# Create a membership of the `u` in the group `g`.
|
|
47
|
+
#
|
|
48
|
+
# membership = UserGroupMembership.create( user: u, group: g )
|
|
49
|
+
#
|
|
50
|
+
def self.create( params )
|
|
51
|
+
if UserGroupMembership.find_by( params ).present?
|
|
52
|
+
raise 'Membership already exists: id = ' + UserGroupMembership.find_by( params ).id.to_s
|
|
53
|
+
else
|
|
54
|
+
user = params[:user]
|
|
55
|
+
user ||= User.find params[:user_id] if params[:user_id]
|
|
56
|
+
user ||= User.find_by_title params[:user_title] if params[:user_title]
|
|
57
|
+
raise "Could not create UserGroupMembership without user." unless user
|
|
58
|
+
|
|
59
|
+
group = params[ :group ]
|
|
60
|
+
group ||= Group.find params[:group_id] if params[:group_id]
|
|
61
|
+
raise "Could not create UserGroupMembership without group." unless group
|
|
62
|
+
|
|
63
|
+
new_membership = DagLink
|
|
64
|
+
.create(ancestor_id: group.id, ancestor_type: 'Group', descendant_id: user.id, descendant_type: 'User')
|
|
65
|
+
.becomes(UserGroupMembership)
|
|
66
|
+
|
|
67
|
+
# This needs to be called manually, since DagLink won't call the proper callback.
|
|
68
|
+
#
|
|
69
|
+
new_membership.set_valid_from_to_now(true)
|
|
70
|
+
new_membership.save
|
|
71
|
+
|
|
72
|
+
return new_membership
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Finder Class Methods
|
|
78
|
+
# ====================================================================================================
|
|
79
|
+
|
|
80
|
+
# Find all memberships that match the given parameters.
|
|
81
|
+
# This method returns an ActiveRecord::Relation object, which means that the result can
|
|
82
|
+
# be chained with scope methods.
|
|
83
|
+
#
|
|
84
|
+
# memberships = UserGroupMembership.find_all_by( user: u )
|
|
85
|
+
# memberships = UserGroupMembership.find_all_by( group: g )
|
|
86
|
+
# memberships = UserGroupMembership.find_all_by( user: u, group: g ).now
|
|
87
|
+
# memberships = UserGroupMembership.find_all_by( user: u, group: g ).in_the_past
|
|
88
|
+
# memberships = UserGroupMembership.find_all_by( user: u, group: g ).now_and_in_the_past
|
|
89
|
+
#
|
|
90
|
+
def self.find_all_by( params )
|
|
91
|
+
user = params[ :user ]
|
|
92
|
+
user ||= User.find params[:user_id] if params[:user_id]
|
|
93
|
+
user ||= User.find_by_title params[:user_title] if params[:user_title]
|
|
94
|
+
group = params[ :group ]
|
|
95
|
+
group ||= Group.find params[:group_id] if params[:group_id]
|
|
96
|
+
links = UserGroupMembership
|
|
97
|
+
.where( :descendant_type => "User" )
|
|
98
|
+
.where( :ancestor_type => "Group" )
|
|
99
|
+
links = links.where( :descendant_id => user.id ) if user
|
|
100
|
+
links = links.where( :ancestor_id => group.id ) if group
|
|
101
|
+
links = links.order('valid_from')
|
|
102
|
+
return links
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Find the first membership that matches the parameters `params`.
|
|
106
|
+
# This is a shortcut for `find_all_by( params ).first`.
|
|
107
|
+
# Use this, if you only expect one membership to be found.
|
|
108
|
+
#
|
|
109
|
+
def self.find_by( params )
|
|
110
|
+
self.find_all_by( params ).limit( 1 ).first
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.find_all_by_user( user )
|
|
114
|
+
self.find_all_by( user: user )
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.find_all_by_group( group )
|
|
118
|
+
self.find_all_by( group: group )
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.find_by_user_and_group( user, group )
|
|
122
|
+
self.find_by( user: user, group: group )
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def self.find_all_by_user_and_group( user, group )
|
|
126
|
+
self.find_all_by( user: user, group: group )
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# Access Methods to Associated User and Group
|
|
131
|
+
# ====================================================================================================
|
|
132
|
+
|
|
133
|
+
def user
|
|
134
|
+
self.descendant
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def user=(new_user)
|
|
138
|
+
self.descendant_id = new_user.id
|
|
139
|
+
self.descendant_type = 'User'
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def user_id
|
|
143
|
+
self.descendant_id
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def user_title
|
|
147
|
+
user.try(:title)
|
|
148
|
+
end
|
|
149
|
+
def user_title=(new_user_title)
|
|
150
|
+
self.user = User.find_by_title(new_user_title)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def group
|
|
154
|
+
self.ancestor
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def group_id
|
|
158
|
+
self.ancestor_id
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def ensure_correct_ancestor_and_descendant_type
|
|
162
|
+
self.ancestor_type = 'Group'
|
|
163
|
+
self.descendant_type = 'User'
|
|
164
|
+
end
|
|
165
|
+
private :ensure_correct_ancestor_and_descendant_type
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# Associated Corporation
|
|
169
|
+
# ====================================================================================================
|
|
170
|
+
|
|
171
|
+
# If this membership is a subgroup membership of a corporation, this method will return the
|
|
172
|
+
# corporation. Otherwise, this will return nil.
|
|
173
|
+
#
|
|
174
|
+
# corporation
|
|
175
|
+
# |-------- group
|
|
176
|
+
# |---( membership )---- user
|
|
177
|
+
#
|
|
178
|
+
# membership = UserGroupMembership.find_by_user_and_group( user, group )
|
|
179
|
+
# membership.corporation == corporation
|
|
180
|
+
#
|
|
181
|
+
def corporation
|
|
182
|
+
if self.group && self.user
|
|
183
|
+
( ( self.group.ancestor_groups + [ self.group ] ) && self.user.corporations ).first
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
# Access Methods to Associated Direct Memberships
|
|
189
|
+
# ====================================================================================================
|
|
190
|
+
|
|
191
|
+
# Returns the direct memberships corresponding to this membership (self).
|
|
192
|
+
# For clarification, consider the following structure:
|
|
193
|
+
#
|
|
194
|
+
# group1
|
|
195
|
+
# |---- group2
|
|
196
|
+
# |---- user
|
|
197
|
+
#
|
|
198
|
+
# user is not a direct member of group1, but an indirect member. But user is a direct member of group2.
|
|
199
|
+
# Thus, this method, called on a membership of user and group1 will return the membership between
|
|
200
|
+
# user and group2.
|
|
201
|
+
#
|
|
202
|
+
# UserGroupMembership.find_by( user: user, group: group1 ).direct_memberships.should
|
|
203
|
+
# include( UserGroupMembership.find_by( user: user, group: group2 ) )
|
|
204
|
+
#
|
|
205
|
+
# An indirect membership can also have several direct memberships, as shown in this figure:
|
|
206
|
+
#
|
|
207
|
+
# group1
|
|
208
|
+
# |--------------- group2
|
|
209
|
+
# | |
|
|
210
|
+
# |---- group3 |
|
|
211
|
+
# |------------- user
|
|
212
|
+
#
|
|
213
|
+
# Here, group2 and grou3 are children of group1. user is member of group2 and group3.
|
|
214
|
+
# Hence, the indirect membership of user and group1 will include both direct memberships.
|
|
215
|
+
#
|
|
216
|
+
def direct_memberships(options = {})
|
|
217
|
+
descendant_groups_of_self_group = self.group.descendant_groups
|
|
218
|
+
descendant_group_ids_of_self_group = descendant_groups_of_self_group.pluck(:id)
|
|
219
|
+
group_ids = descendant_group_ids_of_self_group + [ self.group.id ]
|
|
220
|
+
|
|
221
|
+
memberships = UserGroupMembership
|
|
222
|
+
if options[:with_invalid] || self.read_attribute( :valid_to )
|
|
223
|
+
# If the membership itself is invalidated, also consider the invalidated direct memberships.
|
|
224
|
+
# Otherwise, one has to call `direct_memberships_now_and_in_the_past` rather than
|
|
225
|
+
# `direct_memberships` in order to have the invalidated direct memberships included.
|
|
226
|
+
memberships = memberships.with_invalid
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
memberships = memberships
|
|
230
|
+
.find_all_by_user( self.user )
|
|
231
|
+
.where( :direct => true )
|
|
232
|
+
.where( :ancestor_id => group_ids, :ancestor_type => 'Group' )
|
|
233
|
+
|
|
234
|
+
memberships = memberships.order('valid_from')
|
|
235
|
+
memberships
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def direct_memberships_now_and_in_the_past
|
|
239
|
+
direct_memberships(with_invalid: true)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Returns the direct groups shown in the figures above in the description of
|
|
243
|
+
# `direct_memberships`.
|
|
244
|
+
#
|
|
245
|
+
def direct_groups
|
|
246
|
+
direct_memberships.collect { |membership| membership.group }
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
# Access Methods to Associated Indirect Memberships
|
|
251
|
+
# ====================================================================================================
|
|
252
|
+
|
|
253
|
+
def indirect_memberships
|
|
254
|
+
self.group.ancestor_groups.collect do |ancestor_group|
|
|
255
|
+
UserGroupMembership.with_invalid.find_by_user_and_group(self.user, ancestor_group)
|
|
256
|
+
end.select do |item|
|
|
257
|
+
item != nil
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Methods to Change the Membership
|
|
262
|
+
# ====================================================================================================
|
|
263
|
+
|
|
264
|
+
# Destroy the current membership and move the user over to the given group.
|
|
265
|
+
#
|
|
266
|
+
# group1 group2
|
|
267
|
+
# |---- user => |---- user
|
|
268
|
+
#
|
|
269
|
+
def move_to_group( group_to_move_in, options = {} )
|
|
270
|
+
time = (options[:time] || options[:date] || options[:at] || Time.zone.now).to_datetime
|
|
271
|
+
invalidate at: time
|
|
272
|
+
new_membership = UserGroupMembership.create(user: self.user, group: group_to_move_in)
|
|
273
|
+
new_membership.update_attribute(:valid_from, time)
|
|
274
|
+
return new_membership
|
|
275
|
+
end
|
|
276
|
+
def move_to(group, options = {})
|
|
277
|
+
move_to_group(group, options)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def promote_to( new_group, options = {} )
|
|
281
|
+
self.move_to_group( new_group, options )
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
# Destroy
|
|
286
|
+
# ==========================================================================================
|
|
287
|
+
|
|
288
|
+
# The regular destroy method won't trigger DagLink's callbacks properly,
|
|
289
|
+
# causing the former dag link bug. By calling the DagLink's destroy method
|
|
290
|
+
# we'll ensure the callbacks are called and indirect memberships are destroyed
|
|
291
|
+
# correctly.
|
|
292
|
+
#
|
|
293
|
+
def destroy
|
|
294
|
+
DagLink.where(id: self.id).first.destroy
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
|