Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple models support #54

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6fec326
Add klass names to template
kenzo-tanaka Sep 18, 2022
a86b194
Add default value of klass names
kenzo-tanaka Sep 18, 2022
4ff39eb
Get new params as for switching login class
kenzo-tanaka Sep 18, 2022
ba8ed2c
Add klasses method to any_login.rb
kenzo-tanaka Sep 18, 2022
885e07e
Display login forms
kenzo-tanaka Sep 18, 2022
c95b3e9
Fix `any_login_select` method
kenzo-tanaka Sep 18, 2022
93032fc
Add klass arg to `any_login_previous_select` method
kenzo-tanaka Sep 18, 2022
ca4d982
Add klass arg to `current_user_information` method
kenzo-tanaka Sep 18, 2022
fa9d292
Remove log file
kenzo-tanaka Sep 18, 2022
c8ae86d
Fix default value of klass names
kenzo-tanaka Sep 18, 2022
0fa738f
Fix JavaScript
kenzo-tanaka Sep 18, 2022
c78726b
Fix #any_login -> .any_login
kenzo-tanaka Sep 18, 2022
8c2fb9b
Fix CSS id to class
kenzo-tanaka Sep 18, 2022
a51faae
Remove old form
kenzo-tanaka Sep 18, 2022
a8da931
Fix styles
kenzo-tanaka Sep 18, 2022
6430595
Fix prompt
kenzo-tanaka Sep 18, 2022
992d979
Fix JavaScript
kenzo-tanaka Sep 18, 2022
ac462b1
Fix login method
kenzo-tanaka Sep 18, 2022
6fced36
Fix devise.rb
kenzo-tanaka Sep 18, 2022
228929d
Fix style
kenzo-tanaka Sep 18, 2022
89b45ac
Fix view to pass tests
kenzo-tanaka Sep 19, 2022
a04f90d
Fix id to class
kenzo-tanaka Sep 19, 2022
d6fab62
Fix tests
kenzo-tanaka Sep 19, 2022
d52011f
Fix styles to display all login form
kenzo-tanaka Sep 19, 2022
bc2976e
Add Staff model
kenzo-tanaka Oct 19, 2022
1b36eda
Add devise to staff
kenzo-tanaka Oct 19, 2022
6b26c6b
Fix klass_name to klass_names
kenzo-tanaka Oct 19, 2022
aeb9a5e
Fix model
kenzo-tanaka Oct 19, 2022
3dd3a76
Add test staffs
kenzo-tanaka Oct 19, 2022
a75d80f
Fix routes
kenzo-tanaka Oct 19, 2022
7fedc7c
Fix navigation test
kenzo-tanaka Oct 20, 2022
36adfab
To escape id duplication, specify id = nil
kenzo-tanaka Oct 20, 2022
724b127
Fix navigation test
kenzo-tanaka Oct 20, 2022
99e1b91
tweak
kenzo-tanaka Oct 20, 2022
b4c7f94
Fix icon margin
kenzo-tanaka Nov 28, 2022
c165db5
Update README.md
kenzo-tanaka Nov 28, 2022
9e8d627
Update README.md
kenzo-tanaka Nov 28, 2022
9e40d23
Use existing klass_name option for both single and multi-model support
rbclark Jan 8, 2024
f93cb6b
Remove AnyLogin.klass and utilize klasses everywhere instead.
rbclark Jan 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ In `app/lib/anylogin_omniauth.rb`
```
module AnyloginOmniauth
module Controller
def self.any_login_current_user_method
@@any_login_current_user_method ||= "current_#{AnyLogin.klass.to_s.parameterize.underscore}".to_sym
def self.any_login_current_user_method(klass)
@@any_login_current_user_method ||= "current_#{klass.to_s.parameterize.underscore}".to_sym
end

def any_login_sign_in
Expand All @@ -114,7 +114,7 @@ It will create the initializer file `config/initializers/any_login.rb`.
### Options

- **enabled** - enable or disable gem (by default this gem is enabled only in development mode).
- **klass_name** - class name for "User" object. Defaults to `User`.
- **klass_name** - class name for "User" object. Defaults to `User`. An array of class names is also supported.
- **collection_method** - method which returns collection of users. Sample:
`.all`, `.active`, `.admins`, `.groupped_users`. Value is a simple.
Defaults to `:all`.
Expand All @@ -130,7 +130,6 @@ It will create the initializer file `config/initializers/any_login.rb`.
- **position** - position of AnyLogin box on page. Possible values: `top_left`,
`top_right`, `bottom_left`, `bottom_right`. Default: `bottom_left`.
- **login_button_label** - login button label.
- **select_prompt** - select prompt message.
- **auto_show** - automatically show AnyLogin box.
- **http_basic_authentication_enabled** - Enable HTTP_BASIC authentication.
- **http_basic_authentication_user_name** - HTTP_BASIC authentication user name.
Expand Down
26 changes: 9 additions & 17 deletions app/assets/javascripts/any_login/application.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
function submitOnChange() {
document.getElementById('any_login_form').submit();
}

function elementExists(element) {
return typeof (element) != 'undefined' && element != null;
}

function addChangeListenerTo(elementId) {
let element = document.getElementById(elementId);
if (elementExists(element)) {
element.addEventListener("change", submitOnChange);
}
}

function setupAnyLoginHandlers() {
addChangeListenerTo("back_to_previous_id");
addChangeListenerTo("selected_id");
const forms = document.querySelectorAll('.any_login_form');
forms.forEach(form => {
const selects = form.querySelectorAll('select');
selects.forEach(select => {
select.addEventListener('change', () => {
form.submit();
})
})
})
}

['DOMContentLoaded', 'turbolinks:load', 'turbo:load'].forEach(function(e) {
Expand Down
13 changes: 9 additions & 4 deletions app/assets/stylesheets/any_login/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
cursor: pointer;
vertical-align: middle;
fill: #fff;
margin: 5px;
}

#any_login:hover {
Expand All @@ -77,20 +78,24 @@
color: yellow;
}

#any_login #any_login_id_input {
#any_login .any_login_id_input {
width: 30px;
}

#any_login span#current_user_information {
#any_login span.current_user_information {
display: inline;
}

#any_login span#current_user_information span {
#any_login span.current_user_information span {
display: inline;
}

#any_login span#anylogin_back_to_user {
#any_login span.anylogin_back_to_user {
Comment on lines -92 to +93
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed css id to class, because some login forms would be displayed.

padding-left: 15px;
color: cyan;
display: inline;
}

.any_login_form_toggle_label {
display: inline-block;
}
4 changes: 4 additions & 0 deletions app/controllers/any_login/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def user_id
params[:back_to_previous_id].presence || params[:selected_id].presence || params[:id]
end

def klass
params[:as].constantize
end
Comment on lines +44 to +46
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter is the login class (ex. User, Staff)


def previous
cookies[AnyLogin.cookie_name] ||= ""
end
Expand Down
31 changes: 17 additions & 14 deletions app/views/any_login/_any_login.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
<link rel="stylesheet" href="<%= any_login.css_path %>">

<div id='any_login' class='<%= any_login_klasses %>'>
<%= form_tag any_login.sign_in_path, :method => :post, :id => 'any_login_form' do %>
<label for="any_login_form_toggle" id="any_login_form_toggle_label">
<%= render 'any_login/svg/user', :title => AnyLogin.klass %>
</label>
<input type="checkbox" id="any_login_form_toggle" <%= AnyLogin.auto_show ? "checked" : "" %>>
<span id='any_login_box'>
<%= any_login_select %>
or by
<%= any_login_id_input %>
<%= any_login_submit %>
<span id='current_user_information'><%= current_user_information %></span>
<%= any_login_previous_select %>
</span>
<% end %>
<label for="any_login_form_toggle" class="any_login_form_toggle_label">
<%= render 'any_login/svg/user' %>
</label>
<input type="checkbox" id="any_login_form_toggle" <%= AnyLogin.auto_show ? "checked" : "" %>>

<span id="any_login_box">
<% AnyLogin.klasses.each do |klass| %>
<%= form_tag any_login.sign_in_path(as: klass.to_s), :method => :post, :class => 'any_login_form' do %>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set the login class here.

<%= any_login_select(klass) %>
or by
<%= any_login_id_input %>
<%= any_login_submit %>
<span class='current_user_information'><%= current_user_information(klass) %></span>
<%= any_login_previous_select(klass) %>
<% end %>
<% end %>
</span>
</div>
1 change: 0 additions & 1 deletion app/views/any_login/svg/_user.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" ?>
<svg version="1.1" viewBox="0 0 24 24" height="16" width="16" role="img" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title><%= title %></title>
<g id="info" />
<g id="icons">
<g id="user">
Expand Down
20 changes: 10 additions & 10 deletions lib/any_login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ module Provider
mattr_accessor :login_button_label
@@login_button_label = 'Login'

# prompt message in select
mattr_accessor :select_prompt
@@select_prompt = "Select #{AnyLogin.klass_name}"

# show any_login box by default
mattr_accessor :auto_show
@@auto_show = false
Expand Down Expand Up @@ -88,12 +84,16 @@ def self.setup
yield(self)
end

def self.collection
Collection.new(collection_raw)
def self.collection(klass)
Collection.new(collection_raw(klass))
end

def self.klass
@@klass = AnyLogin.klass_name.constantize
def self.klasses
@@klasses = if AnyLogin.klass_name.is_a?(Array)
AnyLogin.klass_name.map(&:constantize)
else
[AnyLogin.klass_name.constantize]
end
end

def self.cookie_name
Expand All @@ -115,9 +115,9 @@ def self.format_collection_raw(result)
end
end

def self.collection_raw
def self.collection_raw(klass)
@@collection_raw = begin
result = AnyLogin.klass.send(AnyLogin.collection_method)
result = klass.send(AnyLogin.collection_method)
if limit == :none
format_collection_raw(result)
else
Expand Down
27 changes: 14 additions & 13 deletions lib/any_login/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,37 @@ def any_login_here
if AnyLogin.enabled

def any_login_id_input
text_field_tag :id, '', :placeholder => 'ID', :id => 'any_login_id_input', :required => true
text_field_tag :id, '', :placeholder => 'ID', :class => 'any_login_id_input', :required => true
end

def any_login_submit
submit_tag AnyLogin.login_button_label
end

def any_login_select
collection = AnyLogin.collection
def any_login_select(klass)
collection = AnyLogin.collection(klass)
select_options =
if collection.grouped?
grouped_options_for_select(collection.to_a)
else
options_for_select(collection.to_a)
end
select_tag :selected_id, select_options, select_html_options
select_tag :selected_id, select_options, select_html_options(klass).merge(id: nil)
end

def any_login_previous_select
def any_login_previous_select(klass)
ids = any_login_previous_ids
return if ids.blank?

users = ids.collect do |id|
AnyLogin.klass.where(AnyLogin.klass.primary_key => id).first
klass.where(klass.primary_key => id).first
end.compact

collection = AnyLogin::Collection.new(users).to_a
if collection.any?
select_options = options_for_select(collection)
[
content_tag(:span, id: 'anylogin_back_to_user') do
content_tag(:span, class: 'anylogin_back_to_user') do
"History: "
end,
select_tag(:back_to_previous_id, select_options, select_html_options("Back to:"))
Expand All @@ -51,7 +51,8 @@ def any_login_previous_ids
(cookies[AnyLogin.cookie_name].presence || '').split(',').take(AnyLogin.previous_limit)
end

def select_html_options(prompt = AnyLogin.select_prompt)
def select_html_options(klass)
prompt = "Select #{klass}"
options = {}
options[:prompt] = prompt
options
Expand All @@ -63,14 +64,14 @@ def any_login_klasses
klasses.join(' ')
end

def current_user_information
if respond_to?(AnyLogin.provider.constantize::Controller.any_login_current_user_method) &&
user = send(AnyLogin.provider.constantize::Controller.any_login_current_user_method)
def current_user_information(klass)
if respond_to?(AnyLogin.provider.constantize::Controller.any_login_current_user_method(klass)) &&
user = send(AnyLogin.provider.constantize::Controller.any_login_current_user_method(klass))
content_tag :span, :class => 'any_login_user_information' do
if AnyLogin.name_method.is_a?(Symbol)
raw("Current #{AnyLogin.klass_name}: #{h(user.send(AnyLogin.name_method)[0])} &mdash; ID: #{user.id}")
raw("Current #{klass.to_s}: #{h(user.send(AnyLogin.name_method)[0])} &mdash; ID: #{user.id}")
else
raw("Current #{AnyLogin.klass_name}: #{h(AnyLogin.name_method.call(user)[0])} &mdash; ID: #{user.id}")
raw("Current #{klass.to_s}: #{h(AnyLogin.name_method.call(user)[0])} &mdash; ID: #{user.id}")
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/any_login/providers/authlogic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ module Authlogic

module Controller

def self.any_login_current_user_method
@@any_login_current_user_method ||= "current_#{AnyLogin.klass.to_s.parameterize.underscore}".to_sym
def self.any_login_current_user_method(klass)
@@any_login_current_user_method ||= "current_#{klass.to_s.parameterize.underscore}".to_sym
end
rbclark marked this conversation as resolved.
Show resolved Hide resolved

def any_login_sign_in
reset_session
@loginable = AnyLogin.klass.find(user_id)
Object.const_get("#{AnyLogin.klass}Session").create(@loginable)
@loginable = klass.find(user_id)
Object.const_get("#{klass}Session").create(@loginable)
redirect_to main_app.send(AnyLogin.redirect_path_after_login)
end

Expand Down
6 changes: 3 additions & 3 deletions lib/any_login/providers/clearance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ module Clearance

module Controller

def self.any_login_current_user_method
@@any_login_current_user_method ||= "current_#{AnyLogin.klass.to_s.parameterize.underscore}".to_sym
def self.any_login_current_user_method(klass)
@@any_login_current_user_method ||= "current_#{klass.to_s.parameterize.underscore}".to_sym
end

def any_login_sign_in
reset_session
@loginable = AnyLogin.klass.find(user_id)
@loginable = klass.find(user_id)
sign_in @loginable
redirect_to main_app.send(AnyLogin.redirect_path_after_login)
end
Expand Down
12 changes: 6 additions & 6 deletions lib/any_login/providers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ module Controller

DEFAULT_SIGN_IN = proc do |loginable|
reset_session
sign_in Controller.mapping_key, loginable
sign_in Controller.mapping_key(klass), loginable
end

def self.any_login_current_user_method
@@any_login_current_user_method ||= "current_#{mapping_key}".to_sym
def self.any_login_current_user_method(klass)
@@any_login_current_user_method = "current_#{mapping_key(klass)}".to_sym
end

def self.mapping_key
@@mapping_key ||= ::Devise.mappings.detect {|_key, mapping| mapping.class_name == AnyLogin.klass.name }.first
def self.mapping_key(klass)
@@mapping_key = ::Devise.mappings.detect {|_key, mapping| mapping.class_name == klass.name }.first
end

def any_login_sign_in
@loginable = AnyLogin.klass.find(user_id)
@loginable = klass.find(user_id)

sign_in = AnyLogin.sign_in || DEFAULT_SIGN_IN
instance_exec(@loginable, &sign_in)
Expand Down
6 changes: 3 additions & 3 deletions lib/any_login/providers/sorcery.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ module Sorcery

module Controller

def self.any_login_current_user_method
@@any_login_current_user_method ||= "current_#{AnyLogin.klass.to_s.parameterize.underscore}".to_sym
def self.any_login_current_user_method(klass)
@@any_login_current_user_method ||= "current_#{klass.to_s.parameterize.underscore}".to_sym
end

def any_login_sign_in
reset_session
@loginable = AnyLogin.klass.find(user_id)
@loginable = klass.find(user_id)
auto_login @loginable
redirect_to main_app.send(AnyLogin.redirect_path_after_login)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/any_login/templates/any_login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# # enabled or not
# config.enabled = Rails.env.to_s == 'development'

# # Account, User, Person, etc
# # Account, User, Person, etc, or ['Account', 'User', 'Person'] for multiple model support
# config.klass_name = 'User'

# # .all, .active, .admins, .groped_collection, etc ... need to return an array (or hash with arrays) of users
Expand Down
4 changes: 2 additions & 2 deletions test/authlogic/integration/navigation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class NavigationTest < ActionDispatch::IntegrationTest
test "it properly logs users in and allows access to the secret page" do
visit "/"

find("#any_login_form_toggle_label").click
find('#selected_id option:last-of-type').select_option
find(".any_login_form_toggle_label").click
find("select option:last-of-type", match: :first).select_option

visit "/about"

Expand Down
4 changes: 2 additions & 2 deletions test/clearance/integration/navigation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class NavigationTest < ActionDispatch::IntegrationTest
test "it properly logs users in and allows access to the secret page" do
visit "/"

find("#any_login_form_toggle_label").click
find('#selected_id option:last-of-type').select_option
find(".any_login_form_toggle_label").click
find("select option:last-of-type", match: :first).select_option

visit "/about"

Expand Down
4 changes: 2 additions & 2 deletions test/devise/integration/navigation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ class NavigationTest < ActionDispatch::IntegrationTest
test "it properly logs users in and allows access to the secret page" do
visit "/"

find("#any_login_form_toggle_label").click
find(".any_login_form_toggle_label").click
# There is an instability in the test suite where the option on the dropdown sometimes shows
# up as `1` and sometimes shows up as `[email protected]`. This works around the issue.
find('#selected_id option:last-of-type').select_option
find("select option:last-of-type", match: :first).select_option

visit "/about"

Expand Down
6 changes: 6 additions & 0 deletions test/rails_apps/devise/app/models/staff.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Staff < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Loading