Implemented issue#356 - Automatically join users to organizations based on the email address.

This commit is contained in:
Martin Edenhofer 2016-11-13 23:59:39 +01:00
parent eaa603e77b
commit bf3411daca
6 changed files with 262 additions and 1 deletions

View file

@ -13,6 +13,9 @@ class Organization < ApplicationModel
has_many :members, class_name: 'User'
validates :name, presence: true
before_create :domain_cleanup
before_update :domain_cleanup
activity_stream_support permission: 'admin.role'
history_support
search_index_support
@ -21,6 +24,15 @@ class Organization < ApplicationModel
private
def domain_cleanup
return if !domain
return if domain.empty?
domain.gsub!(/@/, '')
domain.gsub!(/\s*/, '')
domain.strip!
domain.downcase!
end
def cache_delete
super

View file

@ -33,7 +33,7 @@ class User < ApplicationModel
include User::SearchIndex
before_validation :check_name, :check_email, :check_login, :check_password
before_create :check_preferences_default, :validate_roles
before_create :check_preferences_default, :validate_roles, :domain_based_assignment
before_update :check_preferences_default, :validate_roles
after_create :avatar_for_email_check
after_update :avatar_for_email_check
@ -856,6 +856,20 @@ returns
}
end
def domain_based_assignment
return if !email
return if organization_id
begin
domain = Mail::Address.new(email).domain
return if !domain
organization = Organization.find_by(domain: domain.downcase, domain_assignment: true)
return if !organization
self.organization_id = organization.id
rescue
return
end
end
def avatar_for_email_check
return if !email
return if email.empty?

View file

@ -125,6 +125,8 @@ class CreateBase < ActiveRecord::Migration
create_table :organizations do |t|
t.string :name, limit: 100, null: false
t.boolean :shared, null: false, default: true
t.string :domain, limit: 250, null: true, default: ''
t.boolean :domain_assignment, null: false, default: false
t.boolean :active, null: false, default: true
t.string :note, limit: 250, null: true, default: ''
t.integer :updated_by_id, null: false
@ -132,6 +134,7 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :organizations, [:name], unique: true
add_index :organizations, [:domain]
create_table :roles_users, id: false do |t|
t.integer :user_id

View file

@ -0,0 +1,85 @@
class OrganizationDomainBasedAssignment < ActiveRecord::Migration
def up
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
add_column :organizations, :domain, :string, limit: 250, null: true, default: ''
add_column :organizations, :domain_assignment, :boolean, null: false, default: false
add_index :organizations, [:domain]
ObjectManager::Attribute.add(
force: true,
object: 'Organization',
name: 'domain_assignment',
display: 'Domain based assignment',
data_type: 'boolean',
data_option: {
null: true,
default: false,
note: 'Assign Users based on users domain.',
item_class: 'formGroup--halfSize',
options: {
true: 'yes',
false: 'no',
},
translate: true,
},
editable: false,
active: true,
screens: {
edit: {
Admin: {
null: false,
},
},
view: {
'-all-' => {
shown: true,
},
},
},
to_create: false,
to_migrate: false,
to_delete: false,
position: 1410,
updated_by_id: 1,
created_by_id: 1,
)
ObjectManager::Attribute.add(
force: true,
object: 'Organization',
name: 'domain',
display: 'Domain',
data_type: 'input',
data_option: {
type: 'text',
maxlength: 150,
null: true,
item_class: 'formGroup--halfSize',
},
editable: false,
active: true,
screens: {
edit: {
'-all-' => {
null: true,
},
},
view: {
'-all-' => {
shown: true,
},
},
},
to_create: false,
to_migrate: false,
to_delete: false,
position: 1420,
updated_by_id: 1,
created_by_id: 1,
)
Cache.clear
end
end

View file

@ -4660,6 +4660,75 @@ ObjectManager::Attribute.add(
position: 1400,
)
ObjectManager::Attribute.add(
force: true,
object: 'Organization',
name: 'domain_assignment',
display: 'Domain based assignment',
data_type: 'boolean',
data_option: {
null: true,
default: false,
note: 'Assign Users based on users domain.',
item_class: 'formGroup--halfSize',
options: {
true: 'yes',
false: 'no',
},
translate: true,
},
editable: false,
active: true,
screens: {
edit: {
Admin: {
null: false,
},
},
view: {
'-all-' => {
shown: true,
},
},
},
to_create: false,
to_migrate: false,
to_delete: false,
position: 1410,
)
ObjectManager::Attribute.add(
force: true,
object: 'Organization',
name: 'domain',
display: 'Domain',
data_type: 'input',
data_option: {
type: 'text',
maxlength: 150,
null: true,
item_class: 'formGroup--halfSize',
},
editable: false,
active: true,
screens: {
edit: {
'-all-' => {
null: true,
},
},
view: {
'-all-' => {
shown: true,
},
},
},
to_create: false,
to_migrate: false,
to_delete: false,
position: 1420,
)
ObjectManager::Attribute.add(
force: true,
object: 'Organization',

View file

@ -0,0 +1,78 @@
# encoding: utf-8
require 'test_helper'
class OrganizationDomainBasedAssignmentTest < ActiveSupport::TestCase
test 'organization based assignment' do
organization1 = Organization.create_if_not_exists(
name: 'organization based assignment 1',
domain: '@examPle1.com ',
domain_assignment: true,
updated_by_id: 1,
created_by_id: 1,
)
organization2 = Organization.create_if_not_exists(
name: 'organization based assignment 2',
domain: 'example2.com',
domain_assignment: false,
updated_by_id: 1,
created_by_id: 1,
)
roles = Role.where(name: 'Customer')
customer1 = User.create_or_update(
login: 'organization-based_assignment-customer1@example1.com',
firstname: 'Domain',
lastname: 'Agent1',
email: 'organization-based_assignment-customer1@example1.com',
password: 'customerpw',
active: true,
roles: roles,
updated_by_id: 1,
created_by_id: 1,
)
assert_equal(organization1.id, customer1.organization_id)
customer2 = User.create_or_update(
login: 'organization-based_assignment-customer2@example1.com',
firstname: 'Domain',
lastname: 'Agent2',
email: 'organization-based_assignment-customer2@example1.com',
password: 'customerpw',
active: true,
organization_id: organization2.id,
roles: roles,
updated_by_id: 1,
created_by_id: 1,
)
assert_equal(organization2.id, customer2.organization_id)
customer3 = User.create_or_update(
login: 'organization-based_assignment-customer3@example2.com',
firstname: 'Domain',
lastname: 'Agent2',
email: 'organization-based_assignment-customer3@example2.com',
password: 'customerpw',
active: true,
roles: roles,
updated_by_id: 1,
created_by_id: 1,
)
assert_equal(nil, customer3.organization_id)
customer4 = User.create_or_update(
login: 'organization-based_assignment-customer4',
firstname: 'Domain',
lastname: 'Agent2',
email: '@',
password: 'customerpw',
active: true,
roles: roles,
updated_by_id: 1,
created_by_id: 1,
)
assert_equal(nil, customer4.organization_id)
end
end