[Git][noosfero/noosfero][master] 2 commits: Allow customization of URL to redirect after login

Bráulio Bhavamitra gitlab at gitlab.com
Mon Aug 10 19:48:50 BRT 2015


Bráulio Bhavamitra pushed to branch master at Noosfero / noosfero


Commits:
e32dafb8 by Braulio Bhavamitra at 2015-08-10T19:19:20Z
Allow customization of URL to redirect after login

Besides, allow session to hold a value for after signup redirection

- - - - -
7e2ac70a by Braulio Bhavamitra at 2015-08-10T19:19:20Z
Add driven_signup plugin

- - - - -


24 changed files:

- app/controllers/public/account_controller.rb
- app/models/environment.rb
- app/models/profile.rb
- + app/views/profile_editor/_redirection_after_login.html.erb
- app/views/profile_editor/edit.html.erb
- + plugins/driven_signup/controllers/admin/driven_signup_plugin/admin_controller.rb
- + plugins/driven_signup/controllers/driven_signup_plugin_admin_controller.rb
- + plugins/driven_signup/controllers/public/driven_signup_plugin/account_controller.rb
- + plugins/driven_signup/db/migrate/20150625143118_create_driven_signup_plugin_token.rb
- + plugins/driven_signup/lib/driven_signup_plugin.rb
- + plugins/driven_signup/lib/driven_signup_plugin/base.rb
- + plugins/driven_signup/lib/ext/environment.rb
- + plugins/driven_signup/lib/ext/user.rb
- + plugins/driven_signup/models/driven_signup_plugin/auth.rb
- + plugins/driven_signup/public/javascripts/driven_signup.js
- + plugins/driven_signup/public/stylesheets/driven_signup.scss
- + plugins/driven_signup/test/functional/account_controller_test.rb
- + plugins/driven_signup/views/driven_signup_plugin/account/signup.html.slim
- + plugins/driven_signup/views/driven_signup_plugin/admin/_auth.html.slim
- + plugins/driven_signup/views/driven_signup_plugin/admin/destroy.js.erb
- + plugins/driven_signup/views/driven_signup_plugin/admin/edit.js.erb
- + plugins/driven_signup/views/driven_signup_plugin/admin/index.html.slim
- + plugins/driven_signup/views/driven_signup_plugin/admin/new.js.erb
- + public/javascripts/redirection_after_login.js


Changes:

=====================================
app/controllers/public/account_controller.rb
=====================================
--- a/app/controllers/public/account_controller.rb
+++ b/app/controllers/public/account_controller.rb
@@ -438,7 +438,7 @@ class AccountController < ApplicationController
   end
 
   def go_to_signup_initial_page
-    check_redirection_options(user, user.environment.redirection_after_signup, user.url)
+    check_redirection_options user, user.environment.redirection_after_signup, user.url, signup: true
   end
 
   def redirect_if_logged_in
@@ -458,8 +458,11 @@ class AccountController < ApplicationController
 
   protected
 
-  def check_redirection_options(user, condition, default)
-    case condition
+  def check_redirection_options user, condition, default, options={}
+    if options[:signup] and target = session.delete(:after_signup_redirect_to)
+      redirect_to target
+    else
+      case condition
       when 'keep_on_same_page'
         redirect_back_or_default(user.admin_url)
       when 'site_homepage'
@@ -472,8 +475,11 @@ class AccountController < ApplicationController
         redirect_to user.admin_url
       when 'welcome_page'
         redirect_to :controller => :home, :action => :welcome, :template_id => (user.template && user.template.id)
-    else
-      redirect_back_or_default(default)
+      when 'custom_url'
+        if (url = user.custom_url_redirection).present? then redirect_to url else redirect_back_or_default default end
+      else
+        redirect_back_or_default(default)
+      end
     end
   end
 


=====================================
app/models/environment.rb
=====================================
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -168,7 +168,8 @@ class Environment < ActiveRecord::Base
       'site_homepage' => _('Redirects the user to the environment homepage.'),
       'user_profile_page' => _('Redirects the user to his profile page.'),
       'user_homepage' => _('Redirects the user to his homepage.'),
-      'user_control_panel' => _('Redirects the user to his control panel.')
+      'user_control_panel' => _('Redirects the user to his control panel.'),
+      'custom_url' => _('Specify the URL to redirect to:'),
     }
   end
   validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true


=====================================
app/models/profile.rb
=====================================
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -3,7 +3,9 @@
 # which by default is the one returned by Environment:default.
 class Profile < ActiveRecord::Base
 
-  attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret
+  attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time,
+    :redirection_after_login, :custom_url_redirection,
+    :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret
 
   # use for internationalizable human type names in search facets
   # reimplement on subclasses
@@ -1023,6 +1025,7 @@ private :generate_url, :url_options
   def preferred_login_redirection
     redirection_after_login.blank? ? environment.redirection_after_login : redirection_after_login
   end
+  settings_items :custom_url_redirection, type: String, default: nil
 
   def remove_from_suggestion_list(person)
     suggestion = person.suggested_profiles.find_by_suggestion_id self.id


=====================================
app/views/profile_editor/_redirection_after_login.html.erb
=====================================
--- /dev/null
+++ b/app/views/profile_editor/_redirection_after_login.html.erb
@@ -0,0 +1,9 @@
+<% content_for :head do %>
+  <%= javascript_include_tag 'redirection_after_login' %>
+<% end %>
+
+<h2><%= _('Page to redirect after login') %></h2>
+<%= f.select :redirection_after_login, Environment.login_redirection_options.map{ |key,value| [value,key] }, selected: @profile.preferred_login_redirection %>
+
+<%= f.text_field :custom_url_redirection %>
+


=====================================
app/views/profile_editor/edit.html.erb
=====================================
--- a/app/views/profile_editor/edit.html.erb
+++ b/app/views/profile_editor/edit.html.erb
@@ -44,8 +44,7 @@
   <% end %>
 
   <% if environment.enabled?('allow_change_of_redirection_after_login') %>
-    <h2><%= _('Page to redirect after login') %></h2>
-    <%=  select 'profile_data', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]}, { :selected => @profile.preferred_login_redirection} %>
+    <%= render 'redirection_after_login', f: f %>
   <% end %>
 
   <h2><%= _('Translations') %></h2>


=====================================
plugins/driven_signup/controllers/admin/driven_signup_plugin/admin_controller.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/controllers/admin/driven_signup_plugin/admin_controller.rb
@@ -0,0 +1,26 @@
+class DrivenSignupPlugin::AdminController < AdminController
+
+  no_design_blocks
+
+  protect 'edit_environment_features', :environment
+
+  def index
+
+  end
+
+  def new
+    @auth = environment.driven_signup_auths.build
+  end
+
+  def edit
+    @auth = environment.driven_signup_auths.where(id: params[:id]).first
+    @auth ||= environment.driven_signup_auths.build
+    @auth.update_attributes params[:auth]
+  end
+
+  def destroy
+    @auth = environment.driven_signup_auths.where(token: params[:token]).first
+    @auth.destroy if @auth
+  end
+
+end


=====================================
plugins/driven_signup/controllers/driven_signup_plugin_admin_controller.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/controllers/driven_signup_plugin_admin_controller.rb
@@ -0,0 +1 @@
+DrivenSignupPluginAdminController = DrivenSignupPlugin::AdminController


=====================================
plugins/driven_signup/controllers/public/driven_signup_plugin/account_controller.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/controllers/public/driven_signup_plugin/account_controller.rb
@@ -0,0 +1,33 @@
+class DrivenSignupPlugin::AccountController < PublicController
+
+  def signup
+    return render_access_denied unless Rails.env.development? or request.post?
+    return render_access_denied unless self.environment.driven_signup_auths.where(token: params[:token]).first
+
+    session[:driven_signup] = true
+    session[:base_organization] = params[:base_organization]
+    session[:find_suborganization] = params[:find_suborganization]
+    session[:suborganization_members_limit] = params[:suborganization_members_limit]
+    session[:user_template] = params[:user_template]
+
+    user_attributes = [:login, :email]
+    user_params = params[:signup].slice *user_attributes
+    profile_params = params[:signup].except *user_attributes
+
+    if current_user and user_params[:email].squish == current_user.email
+      current_user.driven_signup_complete
+      redirect_to session.delete(:after_signup_redirect_to)
+    else
+      self.current_user = nil
+      redirect_to controller: :account, action: :signup, user: user_params, profile_data: profile_params
+    end
+  end
+
+  protected
+
+  def default_url_options
+    # avoid rails' use_relative_controller!
+    {use_route: '/'}
+  end
+
+end


=====================================
plugins/driven_signup/db/migrate/20150625143118_create_driven_signup_plugin_token.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/db/migrate/20150625143118_create_driven_signup_plugin_token.rb
@@ -0,0 +1,16 @@
+class CreateDrivenSignupPluginToken < ActiveRecord::Migration
+
+  def change
+    create_table :driven_signup_plugin_auths do |t|
+      t.integer :environment_id
+      t.string :name
+      t.string :token
+
+      t.timestamps
+    end
+    add_index :driven_signup_plugin_auths, :environment_id
+    add_index :driven_signup_plugin_auths, :token
+    add_index :driven_signup_plugin_auths, [:environment_id, :token]
+  end
+
+end


=====================================
plugins/driven_signup/lib/driven_signup_plugin.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/lib/driven_signup_plugin.rb
@@ -0,0 +1,13 @@
+module DrivenSignupPlugin
+
+  extend Noosfero::Plugin::ParentMethods
+
+  def self.plugin_name
+    _'Driven signup'
+  end
+
+  def self.plugin_description
+    _'Allow external websites to manage the signup'
+  end
+
+end


=====================================
plugins/driven_signup/lib/driven_signup_plugin/base.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/lib/driven_signup_plugin/base.rb
@@ -0,0 +1,3 @@
+class DrivenSignupPlugin::Base < Noosfero::Plugin
+
+end


=====================================
plugins/driven_signup/lib/ext/environment.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/lib/ext/environment.rb
@@ -0,0 +1,7 @@
+require_dependency 'environment'
+
+class Environment
+
+  has_many :driven_signup_auths, class_name: 'DrivenSignupPlugin::Auth', dependent: :destroy
+
+end


=====================================
plugins/driven_signup/lib/ext/user.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/lib/ext/user.rb
@@ -0,0 +1,46 @@
+require_dependency 'user'
+
+class User
+
+  after_create :driven_signup_complete
+
+  protected
+
+  def driven_signup_complete
+    return unless self.session and self.session.delete(:driven_signup)
+
+    base_organization = self.environment.profiles.where(identifier: self.session.delete(:base_organization)).first
+    return unless base_organization
+    organization = base_organization
+
+    if self.session.delete :find_suborganization
+      members_limit = self.session.delete(:suborganization_members_limit).to_i || 50
+      suborganizations = self.environment.profiles.
+        where('identifier <> ?', base_organization.identifier).
+        where('identifier LIKE ?', "#{base_organization.identifier}%").
+        order('identifier ASC')
+      pp suborganizations
+      suborganizations.each do |suborganization|
+        if suborganization.members.count < members_limit
+          organization = suborganization
+          break
+        end
+      end
+    end
+
+    if template = self.environment.profiles.where(identifier: self.session.delete(:user_template)).first
+      self.person.articles.destroy_all
+      self.person.apply_template template
+    end
+
+    # directly affiliate
+    organization.affiliate self.person, Profile::Roles.member(self.environment.id)
+
+    self.person.redirection_after_login = 'custom_url'
+    self.person.custom_url_redirection = Noosfero::Application.routes.url_for organization.url
+    self.person.save
+
+    self.session[:after_signup_redirect_to] = organization.url
+  end
+
+end


=====================================
plugins/driven_signup/models/driven_signup_plugin/auth.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/models/driven_signup_plugin/auth.rb
@@ -0,0 +1,15 @@
+class DrivenSignupPlugin::Auth < ActiveRecord::Base
+
+  attr_accessible :name, :token
+
+  belongs_to :environment
+
+  validates_presence_of :environment
+  validates_presence_of :token
+  validates_uniqueness_of :token, scope: :environment_id
+
+  def token
+    self[:token] ||= SecureRandom.hex 16
+  end
+
+end


=====================================
plugins/driven_signup/public/javascripts/driven_signup.js
=====================================
--- /dev/null
+++ b/plugins/driven_signup/public/javascripts/driven_signup.js
@@ -0,0 +1,22 @@
+driven_signup = {
+
+  admin: {
+    append: function(auth) {
+      return $('#auth-new').before(auth)
+    },
+
+    find: function(token) {
+      return $('#driven-signup-tokens [data-token='+token+']')
+    },
+
+    update: function(token, auth){
+      return this.find(token).replaceWith(auth)
+    },
+
+    remove: function(token) {
+      return this.find(token).remove()
+    },
+  },
+
+}
+


=====================================
plugins/driven_signup/public/stylesheets/driven_signup.scss
=====================================
--- /dev/null
+++ b/plugins/driven_signup/public/stylesheets/driven_signup.scss
@@ -0,0 +1,14 @@
+#driven-signup-tokens {
+
+  &.table {
+    display: table;
+
+    .row {
+      display: table-row;
+
+      .cell {
+        display: table-cell;
+      }
+    }
+  }
+}


=====================================
plugins/driven_signup/test/functional/account_controller_test.rb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/test/functional/account_controller_test.rb
@@ -0,0 +1,45 @@
+require 'test_helper'
+
+# Re-raise errors caught by the controller.
+class AccountController; def rescue_action(e) raise e end; end
+
+class AccountControllerTest < ActionController::TestCase
+
+  def setup
+    @controller = AccountController.new
+    @request = ActionController::TestRequest.new
+    @response = ActionController::TestResponse.new
+
+    e = Environment.default
+    e.enable 'skip_new_user_email_confirmation', true
+    disable_signup_bot_check e
+  end
+
+  should 'use the parameters' do
+    community = create Community, name: 'base', identifier: 'base1'
+    subcommunity = create Community, name: 'sub', identifier: 'base11'
+    subcommunity.reload
+
+    # simulate DrivenSignupPlugin::AccountController
+    session[:driven_signup] = true
+    session[:base_organization] = community.identifier
+    session[:find_suborganization] = true
+    session[:suborganization_members_limit] = 50
+
+    post :signup, user: {login: 'quire', password: 'quire', password_confirmation: 'quire', name: 'quire', email: 'test at example.com'}
+    assert_response :redirect
+    assert_redirected_to subcommunity.url
+
+    user = Profile['quire']
+    assert user
+    assert_includes subcommunity.members, user
+  end
+
+  private
+
+  def disable_signup_bot_check environment = Environment.default
+    environment.min_signup_delay = 0
+    environment.save!
+  end
+
+end


=====================================
plugins/driven_signup/views/driven_signup_plugin/account/signup.html.slim
=====================================
--- /dev/null
+++ b/plugins/driven_signup/views/driven_signup_plugin/account/signup.html.slim


=====================================
plugins/driven_signup/views/driven_signup_plugin/admin/_auth.html.slim
=====================================
--- /dev/null
+++ b/plugins/driven_signup/views/driven_signup_plugin/admin/_auth.html.slim
@@ -0,0 +1,10 @@
+div.row
+  = form_for auth, as: :auth, remote: true, url: {action: :edit, id: auth.id},
+    html: {data: {token: auth.token}} do |f|
+
+    span.cell= f.text_field :name, placeholder: _('name this token')
+    span.cell= f.text_field :token, value: auth.token
+    span.cell= f.submit nil, class: 'btn btn-default btn-success'
+    span.cell= link_to _('Remove'), {action: :destroy, token: auth.token}, remote: true,
+      class: 'btn btn-default btn-danger', confirm: _('Are you sure you want to delete this authorization?')
+


=====================================
plugins/driven_signup/views/driven_signup_plugin/admin/destroy.js.erb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/views/driven_signup_plugin/admin/destroy.js.erb
@@ -0,0 +1,2 @@
+driven_signup.admin.remove(<%=@auth.token.to_json%>)
+


=====================================
plugins/driven_signup/views/driven_signup_plugin/admin/edit.js.erb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/views/driven_signup_plugin/admin/edit.js.erb
@@ -0,0 +1,2 @@
+driven_signup.admin.update(<%=@auth.token.to_json%>, <%= render('auth', auth: @auth).to_json %>)
+


=====================================
plugins/driven_signup/views/driven_signup_plugin/admin/index.html.slim
=====================================
--- /dev/null
+++ b/plugins/driven_signup/views/driven_signup_plugin/admin/index.html.slim
@@ -0,0 +1,11 @@
+= content_for :head do
+  = stylesheet_link_tag 'plugins/driven_signup/stylesheets/driven_signup'
+  = javascript_include_tag 'plugins/driven_signup/javascripts/driven_signup'
+
+div#driven-signup-tokens.table
+  - environment.driven_signup_auths.each do |auth|
+    = render 'auth', auth: auth
+
+  div.row id="auth-new"
+    td= link_to _('New'), {action: :new}, remote: true, class: 'btn btn-default fa-add'
+


=====================================
plugins/driven_signup/views/driven_signup_plugin/admin/new.js.erb
=====================================
--- /dev/null
+++ b/plugins/driven_signup/views/driven_signup_plugin/admin/new.js.erb
@@ -0,0 +1,2 @@
+driven_signup.admin.append(<%= render('auth', auth: @auth).to_json %>)
+


=====================================
public/javascripts/redirection_after_login.js
=====================================
--- /dev/null
+++ b/public/javascripts/redirection_after_login.js
@@ -0,0 +1,24 @@
+redirection_after_login = {
+
+  view: {
+    select: function() {
+      return $('#profile_data_redirection_after_login')
+    },
+    customUrl: function() {
+      return $('#profile_data_custom_url_redirection')
+    },
+  },
+
+  toggleCustomUrl: function() {
+    var view = redirection_after_login.view
+    var formGroup = view.customUrl().parents('.form-group')
+    formGroup.toggle(view.select().val() == 'custom_url')
+  },
+
+};
+
+$(document).ready(function() {
+  redirection_after_login.toggleCustomUrl()
+  $(redirection_after_login.view.select()).on('change keyup', redirection_after_login.toggleCustomUrl)
+})
+



View it on GitLab: https://gitlab.com/noosfero/noosfero/compare/b24e60efb22bd3dbf57a79bed2cc9a97162e25ad...7e2ac70a9d5e6130e2d61fe0547e95535383a42b
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20150810/a94b7124/attachment-0001.html>


More information about the Noosfero-dev mailing list