Merge pull request #321 from warpc/270-user_control
[Refs #270] Admin user control (include ban, protect from mass assigment)
This commit is contained in:
commit
09a3d46303
|
@ -622,6 +622,22 @@ div.rightlist textarea.resizable {
|
||||||
resize: both;
|
resize: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.tablesorter.list-users th.th1 {
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.tablesorter.list-users th.th2 {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.tablesorter.list-users th.th3 {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.tablesorter.list-users th.th4 {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
div.admin-role {
|
div.admin-role {
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
# -*- encoding : utf-8 -*-
|
||||||
|
class Admin::UsersController < ApplicationController
|
||||||
|
before_filter :authenticate_user!
|
||||||
|
load_and_authorize_resource :except => :create
|
||||||
|
authorize_resource :only => :create
|
||||||
|
|
||||||
|
def index
|
||||||
|
@filter = params[:filter] || 'all'
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@user = User.new params[:user]
|
||||||
|
@user.role = params[:role]
|
||||||
|
@user.uname = params[:uname]
|
||||||
|
if @user.save
|
||||||
|
flash[:notice] = t('flash.user.saved')
|
||||||
|
redirect_to users_path
|
||||||
|
else
|
||||||
|
flash[:error] = t('flash.user.save_error')
|
||||||
|
render :action => :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def profile
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@user.role = params[:role]
|
||||||
|
if @user.update_without_password(params[:user])
|
||||||
|
if @user.avatar && params[:delete_avatar] == '1'
|
||||||
|
@user.avatar = nil
|
||||||
|
@user.save
|
||||||
|
end
|
||||||
|
flash[:notice] = t('flash.user.saved')
|
||||||
|
redirect_to users_path#edit_user_path(@user)
|
||||||
|
else
|
||||||
|
flash[:error] = t('flash.user.save_error')
|
||||||
|
flash[:warning] = @user.errors.full_messages.join('. ')
|
||||||
|
render(:action => :profile)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@user.destroy
|
||||||
|
flash[:notice] = t("flash.user.destroyed")
|
||||||
|
redirect_to users_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
colName = ['users.name', 'users.uname', 'users.email']
|
||||||
|
sort_col = params[:iSortCol_0] || 0
|
||||||
|
sort_dir = params[:sSortDir_0]=="asc" ? 'asc' : 'desc'
|
||||||
|
order = "#{colName[sort_col.to_i]} #{sort_dir}"
|
||||||
|
|
||||||
|
@users = @users.paginate(:page => (params[:iDisplayStart].to_i/params[:iDisplayLength].to_i).to_i + 1, :per_page => params[:iDisplayLength])
|
||||||
|
@total_users = @users.count
|
||||||
|
if !params[:sSearch].blank? && search = "%#{params[:sSearch]}%"
|
||||||
|
@users = @users.where('users.name ILIKE ? or users.uname ILIKE ? or users.email ILIKE ?', search, search, search)
|
||||||
|
end
|
||||||
|
@filter = params[:filter] || 'all'
|
||||||
|
@users = @users.send(@filter) if ['real', 'admin', 'banned'].include? @filter
|
||||||
|
@total_user = @users.count
|
||||||
|
@users = @users.order(order)
|
||||||
|
|
||||||
|
render :partial =>'users_ajax', :layout => false
|
||||||
|
end
|
||||||
|
end
|
|
@ -12,7 +12,7 @@ class ApplicationController < ActionController::Base
|
||||||
helper_method :get_owner
|
helper_method :get_owner
|
||||||
|
|
||||||
rescue_from CanCan::AccessDenied do |exception|
|
rescue_from CanCan::AccessDenied do |exception|
|
||||||
redirect_to forbidden_url, :alert => t('flash.exception_message')#:alert => exception.message
|
redirect_to forbidden_url, :alert => t("flash.exception_message")
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -2,57 +2,27 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
before_filter :authenticate_user!
|
before_filter :authenticate_user!
|
||||||
|
|
||||||
load_and_authorize_resource
|
load_and_authorize_resource :only => :show
|
||||||
|
before_filter :set_current_user, :only => [:profile, :update, :private]
|
||||||
autocomplete :user, :uname
|
autocomplete :user, :uname
|
||||||
|
|
||||||
def index
|
|
||||||
@user = User.scoped
|
|
||||||
if !params[:filter].blank? && !params[:filter][:email].blank?
|
|
||||||
@users = @users.where(:email => params[:filter][:email])
|
|
||||||
@email = params[:filter][:email]
|
|
||||||
end
|
|
||||||
@users = @users.paginate(:page => params[:user_page])
|
|
||||||
@action_url = users_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@groups = @user.groups.uniq
|
@groups = @user.groups.uniq
|
||||||
@platforms = @user.platforms.paginate(:page => params[:platform_page], :per_page => 10)
|
@platforms = @user.platforms.paginate(:page => params[:platform_page], :per_page => 10)
|
||||||
@projects = @user.projects.paginate(:page => params[:project_page], :per_page => 10)
|
@projects = @user.projects.paginate(:page => params[:project_page], :per_page => 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
|
||||||
@user = User.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def profile
|
def profile
|
||||||
@user ||= current_user
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@user = User.new params[:user]
|
|
||||||
if @user.save
|
|
||||||
flash[:notice] = t('flash.user.saved')
|
|
||||||
redirect_to users_path
|
|
||||||
else
|
|
||||||
flash[:error] = t('flash.user.save_error')
|
|
||||||
render :action => :new
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if params[:user][:role] && current_user.admin?
|
|
||||||
@user.role = params[:user][:role]
|
|
||||||
params[:user].delete(:role)
|
|
||||||
end
|
|
||||||
@user ||= current_user
|
|
||||||
if @user.update_without_password(params[:user])
|
if @user.update_without_password(params[:user])
|
||||||
if @user.avatar && params[:delete_avatar] == '1'
|
if @user.avatar && params[:delete_avatar] == '1'
|
||||||
@user.avatar = nil
|
@user.avatar = nil
|
||||||
@user.save
|
@user.save
|
||||||
end
|
end
|
||||||
flash[:notice] = t('flash.user.saved')
|
flash[:notice] = t('flash.user.saved')
|
||||||
redirect_to @user == current_user ? edit_profile_path : edit_user_path(@user)
|
redirect_to edit_profile_path
|
||||||
else
|
else
|
||||||
flash[:error] = t('flash.user.save_error')
|
flash[:error] = t('flash.user.save_error')
|
||||||
flash[:warning] = @user.errors.full_messages.join('. ')
|
flash[:warning] = @user.errors.full_messages.join('. ')
|
||||||
|
@ -73,10 +43,10 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
protected
|
||||||
@user.destroy
|
|
||||||
flash[:notice] = t("flash.user.destroyed")
|
def set_current_user
|
||||||
redirect_to users_path
|
@user = current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Group < ActiveRecord::Base
|
||||||
attr_accessible :description
|
attr_accessible :description
|
||||||
attr_readonly :own_projects_count
|
attr_readonly :own_projects_count
|
||||||
|
|
||||||
delegate :ssh_key, :email, :to => :owner
|
delegate :email, :to => :owner
|
||||||
|
|
||||||
after_create :add_owner_to_members
|
after_create :add_owner_to_members
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
ROLES = ['admin']
|
ROLES = ['', 'admin', 'banned']
|
||||||
LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']]
|
LANGUAGES_FOR_SELECT = [['Russian', 'ru'], ['English', 'en']]
|
||||||
LANGUAGES = LANGUAGES_FOR_SELECT.map(&:last)
|
LANGUAGES = LANGUAGES_FOR_SELECT.map(&:last)
|
||||||
MAX_AVATAR_SIZE = 5.megabyte
|
MAX_AVATAR_SIZE = 5.megabyte
|
||||||
|
@ -43,14 +43,16 @@ class User < ActiveRecord::Base
|
||||||
validates :role, :inclusion => {:in => ROLES}, :allow_blank => true
|
validates :role, :inclusion => {:in => ROLES}, :allow_blank => true
|
||||||
validates :language, :inclusion => {:in => LANGUAGES}, :allow_blank => true
|
validates :language, :inclusion => {:in => LANGUAGES}, :allow_blank => true
|
||||||
|
|
||||||
attr_accessible :email, :password, :password_confirmation, :current_password, :remember_me, :login, :name, :ssh_key, :uname, :language,
|
attr_accessible :email, :password, :password_confirmation, :current_password, :remember_me, :login, :name, :language,
|
||||||
:site, :company, :professional_experience, :location, :avatar
|
:site, :company, :professional_experience, :location, :avatar
|
||||||
attr_readonly :uname, :own_projects_count
|
attr_readonly :uname, :own_projects_count
|
||||||
attr_readonly :uname
|
|
||||||
attr_accessor :login
|
attr_accessor :login
|
||||||
|
|
||||||
scope :search_order, order("CHAR_LENGTH(uname) ASC")
|
scope :search_order, order("CHAR_LENGTH(uname) ASC")
|
||||||
scope :search, lambda {|q| where("uname ILIKE ?", "%#{q}%")}
|
scope :search, lambda {|q| where("uname ILIKE ?", "%#{q}%")}
|
||||||
|
scope :banned, where(:role => 'banned')
|
||||||
|
scope :admin, where(:role => 'admin')
|
||||||
|
scope :real, where(:role => ['', nil])
|
||||||
|
|
||||||
after_create lambda { self.create_notifier }
|
after_create lambda { self.create_notifier }
|
||||||
|
|
||||||
|
@ -66,6 +68,10 @@ class User < ActiveRecord::Base
|
||||||
new_record?
|
new_record?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def access_locked?
|
||||||
|
role == 'banned'
|
||||||
|
end
|
||||||
|
|
||||||
def fullname
|
def fullname
|
||||||
return "#{uname} (#{name})"
|
return "#{uname} (#{name})"
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
- content_for :sidebar do
|
||||||
|
.bordered.nopadding
|
||||||
|
%h3= t("layout.users.filter_header")
|
||||||
|
%table
|
||||||
|
- t('layout.users.users_filter').each_key do |base|
|
||||||
|
%tr
|
||||||
|
%td.width18=radio_button_tag :myradio, base, @filter.to_sym == base, {:id => 'users_filter', :class => 'niceRadio', :name => 'filter'}
|
||||||
|
%td.width135=t("layout.users.users_filter.#{base}")
|
||||||
|
.both
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"sEcho": <%=h params[:sEcho].to_i || -1 %>,
|
||||||
|
"iTotalRecords": <%= @total_users %>,
|
||||||
|
"iTotalDisplayRecords": <%= @total_user %>,
|
||||||
|
"aaData": [
|
||||||
|
<% @users.each do |user| %>
|
||||||
|
[
|
||||||
|
"<%= user.name %>",
|
||||||
|
"<%= user.uname %>",
|
||||||
|
"<%= user.email %>",
|
||||||
|
"<span style='<%=user.access_locked? ? 'background: #FEDEDE' : ''%>'><%= user.role %></span>",
|
||||||
|
"<%= j raw [(link_to t('layout.show'), user_path(user) if can? :read, user),
|
||||||
|
(link_to t('layout.edit'), edit_user_path(user) if can? :edit, user),
|
||||||
|
(link_to t('layout.delete'), delete_user_path(user), :method => :delete, :confirm => t('layout.users.confirm_delete') if can? :destroy, user)
|
||||||
|
].compact.join(' | ') %>"
|
||||||
|
]<%= user == @users.last ? '' : ',' %>
|
||||||
|
<% end %>
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
%h3.fix= t("layout.users.list_header")
|
||||||
|
- if can? :create, User.new
|
||||||
|
= link_to t("layout.users.new"), new_user_path, :class => 'button'
|
||||||
|
|
||||||
|
- columns = [{:type => 'html'}, {:type => 'html'}, {:type => 'html'}, {:type => 'html', :sortable => false, :searchable => false}, {:type => nil, :sortable => false, :searchable => false, :class => 'buttons'}]
|
||||||
|
= raw datatable(columns, {:sort_by => "[0, 'asc']", :processing => t("layout.processing"),
|
||||||
|
:pagination_labels => {:previous => t("datatables.previous_label"), :next => t("datatables.next_label")},
|
||||||
|
:empty_label => t("datatables.empty_label"),
|
||||||
|
:info_label => t("datatables.info_label"),
|
||||||
|
:info_empty_label => t("datatables.info_empty_label"),
|
||||||
|
:filtered_label => t("datatables.filtered_label"),
|
||||||
|
:table_dom_id => 'datatable',
|
||||||
|
:auto_width => 'false',
|
||||||
|
:ajax_source => "#{url_for :controller => 'admin/users', :action => :list}",
|
||||||
|
:additional_data => {:filter => "' + $('#users_filter[type=\"radio\"]:checked').val() + '"} })
|
||||||
|
|
||||||
|
%table#datatable.tablesorter.list-users{:cellspacing => 0, :cellpadding => 0}
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th.th1= t("activerecord.attributes.user.name")
|
||||||
|
%th.th2= t("activerecord.attributes.user.uname")
|
||||||
|
%th.th3= t("activerecord.attributes.user.email")
|
||||||
|
%th.th4= t("activerecord.attributes.user.role")
|
||||||
|
%th.last
|
||||||
|
%tbody
|
||||||
|
%br
|
||||||
|
|
||||||
|
= render :partial => 'admin/users/sidebar'
|
||||||
|
= render 'admin/submenu'
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$('#users_filter[type="radio"]').live('change', function(){
|
||||||
|
$('#datatable').dataTable().fnDraw();
|
||||||
|
});
|
|
@ -0,0 +1,10 @@
|
||||||
|
.block
|
||||||
|
.content
|
||||||
|
%h2.title= t("layout.users.new_header")
|
||||||
|
.inner
|
||||||
|
= form_for @user, :url => users_path, :html => { :class => :form } do |f|
|
||||||
|
= render :partial => "users/form", :locals => {:f => f}
|
||||||
|
|
||||||
|
- content_for :sidebar do
|
||||||
|
.bordered.nopadding
|
||||||
|
= render 'admin/submenu'
|
|
@ -0,0 +1,16 @@
|
||||||
|
%h3.fix.bpadding10= @user.uname
|
||||||
|
|
||||||
|
= form_for @user, :url => update_user_path(@user), :html => { :class => :form } do |f|
|
||||||
|
= render :partial => "users/form", :locals => {:f => f}
|
||||||
|
|
||||||
|
.notify
|
||||||
|
%p= t('layout.users.public_data_edit_warning')
|
||||||
|
.notify
|
||||||
|
%p= t('layout.users.avatar_notice')
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$('article .right').addClass('middlepadding');
|
||||||
|
|
||||||
|
= render 'admin/submenu'
|
||||||
|
- content_for :sidebar do
|
||||||
|
.bordered.nopadding
|
|
@ -7,15 +7,17 @@
|
||||||
.logo
|
.logo
|
||||||
/ Page
|
/ Page
|
||||||
%article
|
%article
|
||||||
- is_error = (flash.try(:first).try(:first) == :alert && flash.try(:first).try(:last) == t('devise.failure.invalid')) # Trash
|
- if flash.try(:first).try(:first) == :alert && [t('devise.failure.invalid'), t('devise.failure.locked')].include?(flash.try(:first).try(:last))
|
||||||
|
- error = flash.first.last
|
||||||
|
- error ||= false
|
||||||
- login = t('devise.sessions.login'); password = t('devise.sessions.password')
|
- login = t('devise.sessions.login'); password = t('devise.sessions.password')
|
||||||
=hidden_field_tag :login_default, login
|
=hidden_field_tag :login_default, login
|
||||||
=hidden_field_tag :password_default, password
|
=hidden_field_tag :password_default, password
|
||||||
= form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "form login" }) do |f|
|
= form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "form login" }) do |f|
|
||||||
%h1= title t("layout.sessions.sign_in_header")
|
%h1= title t("layout.sessions.sign_in_header")
|
||||||
= f.text_field :login, :class => "registartion-input #{is_error ? "registartion-input-error" : ''}", :value => login
|
= f.text_field :login, :class => "registartion-input #{error ? "registartion-input-error" : ''}", :value => login
|
||||||
%br/
|
%br/
|
||||||
= f.password_field :password, :class => "registartion-input #{is_error ? "registartion-input-error" : ''}", :value => password
|
= f.password_field :password, :class => "registartion-input #{error ? "registartion-input-error" : ''}", :value => password
|
||||||
%br/
|
%br/
|
||||||
.registration
|
.registration
|
||||||
.remember
|
.remember
|
||||||
|
@ -30,4 +32,4 @@
|
||||||
.forgot
|
.forgot
|
||||||
.password
|
.password
|
||||||
%p= link_to t("layout.devise.shared_links.forgot_password"), new_password_path(resource_name)
|
%p= link_to t("layout.devise.shared_links.forgot_password"), new_password_path(resource_name)
|
||||||
=showDeviseHintError(:login_error, is_error ? t('devise.failure.invalid') : false)
|
=showDeviseHintError(:login_error, error)
|
||||||
|
|
|
@ -18,4 +18,4 @@
|
||||||
.actions-bar.wat-cf
|
.actions-bar.wat-cf
|
||||||
.actions= will_paginate
|
.actions= will_paginate
|
||||||
|
|
||||||
= render 'admins/submenu'
|
= render 'admin/submenu'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
%ul
|
%ul
|
||||||
- (collection = t which_menu).each do |base, title|
|
- (collection = t which_menu).each do |base, title|
|
||||||
- if can? :index, base.to_s.classify.constantize
|
- if can? :index, base.to_s.classify.constantize
|
||||||
%li= link_to title, send(:"#{base}_path"), :class => [].tap{|c| c << 'active' if params[:controller] == base.to_s}.join(' ')
|
%li= link_to title, send(:"#{base}_path"), :class => controller_name == base.to_s ? 'active' : ''
|
||||||
- if current_user.admin? && which_menu == 'top_menu'
|
- if current_user.admin? && which_menu == 'top_menu'
|
||||||
%li= link_to 'Admin', users_path, :class => t('admins_menu').has_key?(params[:controller].to_sym) ? 'active' : ''
|
%li= link_to 'Admin', users_path, :class => t('admins_menu').has_key?(controller_name.to_sym) ? 'active' : ''
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
- if current_user.admin?
|
||||||
|
.leftlist
|
||||||
|
= f.label :role, t("activerecord.attributes.user.role"), :class => :label
|
||||||
|
.rightlist
|
||||||
|
= f.select :role, User::ROLES, {}, {:name => 'role'}
|
||||||
|
- if @user.new_record?
|
||||||
|
.leftlist
|
||||||
|
= f.label :uname, t("activerecord.attributes.user.uname")
|
||||||
|
.rightlist
|
||||||
|
= f.text_field :uname, :name => 'uname'
|
||||||
|
.leftlist
|
||||||
|
= f.label :password, t("activerecord.attributes.user.password")
|
||||||
|
.rightlist
|
||||||
|
= f.password_field :password
|
||||||
|
.both
|
||||||
|
.leftlist
|
||||||
|
= f.label :password_confirmation, t("activerecord.attributes.user.password_confirm")
|
||||||
|
.rightlist
|
||||||
|
= f.password_field :password_confirmation
|
||||||
|
.both
|
||||||
.leftlist
|
.leftlist
|
||||||
= f.label :name, t("activerecord.attributes.user.name")
|
= f.label :name, t("activerecord.attributes.user.name")
|
||||||
.rightlist
|
.rightlist
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
.admin-preferences
|
.admin-preferences
|
||||||
%ul
|
%ul
|
||||||
- if can? :edit, @user
|
- if can? :edit, @user
|
||||||
%li{:class => (act == :edit && :users == contr) ? 'active' : ''}
|
%li{:class => (act == :profile && :users == contr) ? 'active' : ''}
|
||||||
= link_to t("layout.users.profile"), @user == current_user ? edit_profile_path : edit_user_path(@user)
|
= link_to t("layout.users.profile"), @user == current_user ? edit_profile_path : edit_user_path(@user)
|
||||||
- if can? :private, @user
|
- if can? :private, @user
|
||||||
%li{:class => (act == :private && contr == :users) ? 'active' : ''}
|
%li{:class => (act == :private && contr == :users) ? 'active' : ''}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
.block
|
|
||||||
.secondary-navigation
|
|
||||||
%ul.wat-cf
|
|
||||||
%li.first.active= link_to t("layout.users.list"), users_path
|
|
||||||
%li= link_to t("layout.users.new"), new_user_path
|
|
||||||
%li= link_to t("layout.users.register_requests"), register_requests_path if can? :read, RegisterRequest
|
|
||||||
.content
|
|
||||||
%h2.title
|
|
||||||
= t("layout.users.list_header")
|
|
||||||
.inner
|
|
||||||
= render :partial => "users/filter", :action_url => @action_url
|
|
||||||
.inner
|
|
||||||
%table.table
|
|
||||||
%tr
|
|
||||||
%th.first ID
|
|
||||||
%th= t("activerecord.attributes.user.name")
|
|
||||||
%th= t("activerecord.attributes.user.uname")
|
|
||||||
%th= t("activerecord.attributes.user.email")
|
|
||||||
%th= t("activerecord.attributes.user.role")
|
|
||||||
%th.last
|
|
||||||
- @users.each do |user|
|
|
||||||
%tr{:class => cycle("odd", "even")}
|
|
||||||
%td= user.id
|
|
||||||
%td= link_to user.name, user_path(user)
|
|
||||||
%td= link_to user.uname, user_path(user)
|
|
||||||
%td= user.email
|
|
||||||
%td= user.role
|
|
||||||
%td.last
|
|
||||||
- if can? :read, user
|
|
||||||
= link_to t("layout.show"), user_path(user)
|
|
||||||
\|
|
|
||||||
- if can? :edit, user
|
|
||||||
#{link_to t("layout.edit"), edit_user_path(user)}
|
|
||||||
\|
|
|
||||||
- if can? :destroy, user
|
|
||||||
#{link_to t("layout.delete"), user_path(user), :method => :delete, :confirm => t("layout.users.confirm_delete")}
|
|
||||||
.actions-bar.wat-cf
|
|
||||||
.actions= will_paginate @users, :param_name => :user_page
|
|
||||||
= render 'admins/submenu'
|
|
|
@ -1,12 +0,0 @@
|
||||||
.block
|
|
||||||
.secondary-navigation
|
|
||||||
%ul.wat-cf
|
|
||||||
%li.first= link_to t("layout.users.list"), users_path
|
|
||||||
%li.active= link_to t("layout.users.new"), new_user_path
|
|
||||||
.content
|
|
||||||
%h2.title= t("layout.users.new_header")
|
|
||||||
.inner
|
|
||||||
= form_for @user, :url => users_path, :html => { :class => :form } do |f|
|
|
||||||
= render :partial => "form", :locals => {:f => f}
|
|
||||||
|
|
||||||
- content_for :sidebar, render('sidebar')
|
|
|
@ -1,12 +1,7 @@
|
||||||
%h3.fix.bpadding10= @user.uname
|
%h3.fix.bpadding10= @user.uname
|
||||||
|
|
||||||
= form_for @user, :url => user_path(@user), :html => { :class => :form } do |f|
|
= form_for @user, :url => user_path(@user), :html => { :class => :form } do |f|
|
||||||
- if current_user.admin?
|
= render :partial => "users/form", :locals => {:f => f}
|
||||||
.leftlist
|
|
||||||
= f.label :role, t("activerecord.attributes.user.role"), :class => :label
|
|
||||||
.rightlist
|
|
||||||
= f.select :role, User::ROLES, :include_blank => true
|
|
||||||
= render :partial => "form", :locals => {:f => f}
|
|
||||||
|
|
||||||
.notify
|
.notify
|
||||||
%p= t('layout.users.public_data_edit_warning')
|
%p= t('layout.users.public_data_edit_warning')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.left
|
.left
|
||||||
= image_tag avatar_url(@user, :big)
|
= image_tag avatar_url(@user, :big)
|
||||||
%br
|
%br
|
||||||
= link_to t("layout.users.settings"), edit_user_path(@user), :class => 'button width81' if can? :edit, @user
|
= link_to t("layout.users.settings"), current_user == @user ? edit_profile_path : edit_user_path(@user), :class => 'button width81' if can? :edit, @user
|
||||||
.left
|
.left
|
||||||
%h3= @user.uname
|
%h3= @user.uname
|
||||||
= @user.name
|
= @user.name
|
||||||
|
|
|
@ -25,6 +25,11 @@ en:
|
||||||
avatar_notice: Without uploaded avatar will be used avatar from gravar web service.
|
avatar_notice: Without uploaded avatar will be used avatar from gravar web service.
|
||||||
delete_avatar: Delete avatar
|
delete_avatar: Delete avatar
|
||||||
avatar_with_size: Avatar (less than %{max})
|
avatar_with_size: Avatar (less than %{max})
|
||||||
|
users_filter:
|
||||||
|
all: All
|
||||||
|
admin: Admins
|
||||||
|
real: Real
|
||||||
|
banned: Banned
|
||||||
|
|
||||||
activerecord:
|
activerecord:
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -22,9 +22,14 @@ ru:
|
||||||
delete_header: Удалить аккаунт
|
delete_header: Удалить аккаунт
|
||||||
delete_warning: Внимание! Удаленный аккаунт восстановлению не подлежит.
|
delete_warning: Внимание! Удаленный аккаунт восстановлению не подлежит.
|
||||||
private_settings_header: Изменение пароля
|
private_settings_header: Изменение пароля
|
||||||
avatar_notice: При отсутствии загруженной аватарки будет использована Ваша аватарка на сервисе gravatar.
|
avatar_notice: При отсутствии загруженного аватара будет использован Ваш аватар на сервисе gravatar.
|
||||||
delete_avatar: Удалить аватар
|
delete_avatar: Удалить аватар
|
||||||
avatar_with_size: Аватар (менее %{max})
|
avatar_with_size: Аватар (менее %{max})
|
||||||
|
users_filter:
|
||||||
|
all: Все
|
||||||
|
admin: Админы
|
||||||
|
real: Обычные
|
||||||
|
banned: Забаненные
|
||||||
|
|
||||||
activerecord:
|
activerecord:
|
||||||
attributes:
|
attributes:
|
||||||
|
|
|
@ -5,14 +5,19 @@ Rosa::Application.routes.draw do
|
||||||
|
|
||||||
devise_scope :user do
|
devise_scope :user do
|
||||||
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
|
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
|
||||||
get '/user' => 'users#profile', :as => 'edit_profile'
|
get '/user' => 'users#profile', :as => :edit_profile
|
||||||
put '/user' => 'users#update', :as => 'update_profile'
|
put '/user' => 'users#update', :as => :update_profile
|
||||||
get '/users/:id/edit' => 'users#profile', :as => 'edit_user'
|
get '/users' => 'admin/users#index', :as => :users
|
||||||
put '/users/:id/edit' => 'users#update', :as => 'update_user'
|
get '/users/new' => 'admin/users#new', :as => :new_user
|
||||||
|
get '/users/list' => 'admin/users#list', :as => :users_list
|
||||||
|
post '/users' => 'admin/users#create', :as => :create_user
|
||||||
|
get '/users/:id/edit' => 'admin/users#profile', :as => :edit_user
|
||||||
|
put '/users/:id/edit' => 'admin/users#update', :as => :update_user
|
||||||
|
delete '/users/:id/delete' => 'admin/users#destroy', :as => :delete_user
|
||||||
end
|
end
|
||||||
devise_for :users, :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'}
|
devise_for :users, :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'}
|
||||||
|
|
||||||
resources :users do
|
resources :users, :only => [:show, :profile, :update] do
|
||||||
resources :groups, :only => [:new, :create, :index]
|
resources :groups, :only => [:new, :create, :index]
|
||||||
collection do
|
collection do
|
||||||
resources :register_requests, :only => [:index, :new, :create, :show_message, :approve, :reject] do
|
resources :register_requests, :only => [:index, :new, :create, :show_message, :approve, :reject] do
|
||||||
|
@ -27,6 +32,7 @@ Rosa::Application.routes.draw do
|
||||||
namespace :settings do
|
namespace :settings do
|
||||||
resource :notifier, :only => [:show, :update]
|
resource :notifier, :only => [:show, :update]
|
||||||
end
|
end
|
||||||
|
resources :platforms, :only => [:new, :create]
|
||||||
end
|
end
|
||||||
match 'users/:id/settings/private' => 'users#private', :as => :user_private_settings, :via => :get
|
match 'users/:id/settings/private' => 'users#private', :as => :user_private_settings, :via => :get
|
||||||
match 'users/:id/settings/private' => 'users#private', :as => :user_private_settings, :via => :put
|
match 'users/:id/settings/private' => 'users#private', :as => :user_private_settings, :via => :put
|
||||||
|
@ -182,14 +188,14 @@ Rosa::Application.routes.draw do
|
||||||
delete :remove
|
delete :remove
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
resources :users, :groups do
|
|
||||||
resources :platforms, :only => [:new, :create]
|
resources :platforms, :only => [:new, :create]
|
||||||
|
|
||||||
# resources :repositories, :only => [:new, :create]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# resources :users, :groups do
|
||||||
|
# resources :platforms, :only => [:new, :create]
|
||||||
|
# resources :repositories, :only => [:new, :create]
|
||||||
|
# end
|
||||||
|
|
||||||
resources :activity_feeds, :only => [:index]
|
resources :activity_feeds, :only => [:index]
|
||||||
|
|
||||||
resources :search, :only => [:index]
|
resources :search, :only => [:index]
|
||||||
|
|
|
@ -12,7 +12,7 @@ module Grack
|
||||||
return render_not_found if project.blank?
|
return render_not_found if project.blank?
|
||||||
|
|
||||||
return ::Rack::Auth::Basic.new(@app) do |u, p|
|
return ::Rack::Auth::Basic.new(@app) do |u, p|
|
||||||
user = User.find_for_database_authentication(:login => u) and user.valid_password?(p) and
|
user = User.find_for_database_authentication(:login => u) and !user.access_locked? and user.valid_password?(p) and
|
||||||
ability = ::Ability.new(user) and ability.can?(action, project) # project.members.include?(user)
|
ability = ::Ability.new(user) and ability.can?(action, project) # project.members.include?(user)
|
||||||
end.call(env) unless project.public? and read? # need auth
|
end.call(env) unless project.public? and read? # need auth
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,52 +1,30 @@
|
||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
shared_examples_for 'user with users list viewer rights' do
|
|
||||||
it 'should be able to perform index action' do
|
|
||||||
get :index
|
|
||||||
response.should render_template(:index)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should assigns 5 users without filter params' do
|
|
||||||
get :index
|
|
||||||
assigns[:users].count.should == 5
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should find one user' do
|
|
||||||
get :index, :filter => {:email => "user1@nonexistanceserver.com"}
|
|
||||||
assigns[:users].size == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should find user with searchable email' do
|
|
||||||
get :index, :filter => {:email => "user1@nonexistanceserver.com"}
|
|
||||||
assigns[:users].first.email.should == "user1@nonexistanceserver.com"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe UsersController do
|
describe UsersController do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
stub_rsync_methods
|
stub_rsync_methods
|
||||||
|
|
||||||
@simple_user = Factory(:user)
|
@simple_user = Factory(:user)
|
||||||
|
@other_user = Factory(:user)
|
||||||
@admin = Factory(:admin)
|
@admin = Factory(:admin)
|
||||||
%w[user1 user2 user3].each do |uname|
|
%w[user1 user2 user3].each do |uname|
|
||||||
Factory(:user, :uname => uname, :email => "#{ uname }@nonexistanceserver.com")
|
Factory(:user, :uname => uname, :email => "#{ uname }@nonexistanceserver.com")
|
||||||
end
|
end
|
||||||
end
|
@update_params = {:email => 'new_email@test.com'}
|
||||||
|
|
||||||
context 'for global admin' do
|
|
||||||
before(:each) do
|
|
||||||
set_session_for(@admin)
|
|
||||||
end
|
|
||||||
|
|
||||||
it_should_behave_like 'user with users list viewer rights'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for guest' do
|
context 'for guest' do
|
||||||
it 'should not be able to perform index action' do
|
it 'should not be able to view profile' do
|
||||||
get :index
|
get :profile
|
||||||
response.should redirect_to(new_user_session_path)
|
response.should redirect_to(new_user_session_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should not be able to update other profile' do
|
||||||
|
get :update, {:id => @other_user.id}.merge(@update_params)
|
||||||
|
response.should redirect_to(new_user_session_path)
|
||||||
|
@other_user.reload.email.should_not == @update_params[:email]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for simple user' do
|
context 'for simple user' do
|
||||||
|
@ -54,9 +32,23 @@ describe UsersController do
|
||||||
set_session_for(@simple_user)
|
set_session_for(@simple_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not be able to perform index action' do
|
it 'should be able to view profile' do
|
||||||
get :index
|
get :profile
|
||||||
response.should redirect_to(forbidden_path)
|
response.code.should eq('200')
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with mass assignment' do
|
||||||
|
it 'should not be able to update uname' do
|
||||||
|
@simple_user.should_not allow_mass_assignment_of :uname
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not be able to update role' do
|
||||||
|
@simple_user.should_not allow_mass_assignment_of :role
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not be able to update other user' do
|
||||||
|
@simple_user.should_not allow_mass_assignment_of :id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue