Project

General

Profile

« Previous | Next » 

Revision d5953972

Added by Jan Pazdziora about 10 years ago

fixes #5241 - Add support for external user groups.

View differences:

app/models/auth_source.rb
before_destroy EnsureNotUsedBy.new(:users)
has_many :users
has_many :external_usergroups, :dependent => :destroy
validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 60 }
scope :non_internal, lambda { where("type <> ?", 'AuthSourceInternal') }
def authenticate(login, password)
end
app/models/external_usergroup.rb
class ExternalUsergroup < ActiveRecord::Base
belongs_to :usergroup, :inverse_of => :external_usergroups
belongs_to :auth_source
validates_uniqueness_of :name, :scope => :auth_source_id
validates_presence_of :name, :auth_source, :usergroup
end
app/models/usergroup.rb
has_many :usergroup_members, :dependent => :destroy
has_many :users, :through => :usergroup_members, :source => :member, :source_type => 'User', :dependent => :destroy
has_many :usergroups, :through => :usergroup_members, :source => :member, :source_type => 'Usergroup', :dependent => :destroy
has_many :external_usergroups, :dependent => :destroy, :inverse_of => :usergroup
has_many :cached_usergroup_members
has_many :usergroup_parents, :dependent => :destroy, :foreign_key => 'member_id',
......
scoped_search :on => :name, :complete_value => :true
validate :ensure_uniq_name
accepts_nested_attributes_for :external_usergroups, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
# This methods retrieves all user addresses in a usergroup
# Returns: Array of strings representing the user's email addresses
def recipients
......
errors.add :name, _("is already used by a user account") if User.where(:login => name).first
end
def add_users(userlist)
users << User.where( {:login => userlist } )
end
def remove_users(userlist)
old_users = User.select { |user| userlist.include?(user.login) }
self.users = self.users - old_users
end
end
app/services/foreman/access_permissions.rb
}
end
map.security_block :external_usergroups do |map|
map.permission :view_external_usergroups, { :external_usergroups => [:index, :show ] }
map.permission :create_external_usergroups, { :external_usergroups => [:new, :create] }
map.permission :edit_external_usergroups, { :external_usergroups => [:edit, :update] }
map.permission :destroy_external_usergroups, { :external_usergroups => [:destroy] }
end
map.security_block :users do |map|
ajax_actions = [:auth_source_selected]
app/views/usergroups/_external.html.erb
<div class='fields'>
<div class="form-group">
<%= field_set_tag _("External user group").html_safe + " #{remove_child_link('x', f, { :rel => 'twipsy', "data-title" => _('remove external user group'), :'data-placement' => 'left', :class => 'fr badge badge-danger'})}".html_safe, :id => 'external_usergroup' do %>
<%= text_f f, :name %>
<%= select_f f, :auth_source_id, AuthSource.non_internal, :id, :to_label %>
<% end %>
</div>
</div>
app/views/usergroups/_form.html.erb
<%= javascript 'lookup_keys' %>
<%= form_for @usergroup do |f| %>
<%= base_errors_for @usergroup %>
<ul class="nav nav-tabs" data-tabs="tabs">
<li class="active"><a href="#primary" data-toggle="tab"><%= _("Usergroup") %></a></li>
<li><a href="#roles" data-toggle="tab"><%= _("Roles") %></a></li>
<% if AuthSource.non_internal.present? %>
<li><a href="#external" data-toggle="tab"><%= _("External groups") %></a></li>
<% end %>
</ul>
<div class="tab-content">
......
<%= checkbox_f f, :admin if User.current.can_change_admin_flag? %>
<%= multiple_checkboxes f, :roles, @usergroup, Role.givable.for_current_user, {:label => _('Roles')} %>
</div>
<% if AuthSource.non_internal.present? %>
<div class="tab-pane" id="external">
<table class="table table-bordered table-striped table-two-pane">
<tr>
<th><%= s_("Usergroup|Name") %></th>
<th><%= s_("Usergroup|Auth source") %></th>
</tr>
<% @usergroup.external_usergroups.each do |usergroup| %>
<tr>
<td><%= h usergroup.name %></td>
<td><%= h usergroup.auth_source %></td>
</tr>
<% end %>
</table>
<button class='btn btn-info' type='button'
onclick="$('#current_external_usergroups').toggle();"><%= _("Show linked external user groups") %></button>
<hr>
<div style='display:none' id='current_external_usergroups'>
<%= f.fields_for :external_usergroups do |ug| %>
<%= render 'external', :f => ug %>
<% end %>
<hr>
</div>
<div class="children_fields">
<%= new_child_fields_template(f, :external_usergroups, { :partial => 'external' } ) %>
<%= add_child_link '+ ' + _('Add external user group'), :external_usergroups, { :class => "info disable-unsupported", :title => _('link external user group with this user group') } %>
</div>
</div>
<% end %>
</div>
<%= submit_or_cancel f %>
app/views/usergroups/index.html.erb
<%= javascript 'lookup_keys' %>
<% title _("User Groups") %>
<% title_actions display_link_if_authorized(_("New User group"), hash_for_new_usergroup_path) %>
db/migrate/20140409031625_create_external_usergroups.rb
class CreateExternalUsergroups < ActiveRecord::Migration
def change
create_table :external_usergroups do |t|
t.string :name, :null => false
t.integer :auth_source_id, :null => false
t.integer :usergroup_id, :null => false
end
add_index :external_usergroups, :usergroup_id
add_foreign_key "external_usergroups", "usergroups", :name => "external_usergroups_usergroup_id_fk"
add_foreign_key "external_usergroups", "auth_sources", :name => "external_usergroups_auth_source_id_fk"
end
end
test/unit/usergroup_test.rb
assert_equal 2, user.reload.cached_user_roles.size
end
test 'add_users adds users in list and does not add nonexistent users' do
usergroup = FactoryGirl.create(:usergroup)
usergroup.send(:add_users, ['one', 'two', 'three'])
# users 'one' 'two' are defined in fixtures, 'three' is not defined
assert_equal ['one', 'two'], usergroup.users.map(&:login)
end
test 'remove_users removes user list' do
usergroup = FactoryGirl.create(:usergroup)
usergroup.send(:add_users, ['one', 'two'])
usergroup.send(:remove_users, ['one', 'two'])
assert_equal [], usergroup.users
end
# TODO test who can modify usergroup roles and who can assign users!!! possible privileges escalation
end

Also available in: Unified diff