Commit c9def945d4222eeb8026a0311495259bf99267a1
1 parent
c0df0cd7
Exists in
master
and in
4 other branches
User blocking improved. Admin area styled
Showing
13 changed files
with
231 additions
and
109 deletions
Show diff stats
CHANGELOG
app/assets/stylesheets/gitlab_bootstrap.scss
| ... | ... | @@ -450,3 +450,17 @@ form { |
| 450 | 450 | } |
| 451 | 451 | |
| 452 | 452 | } |
| 453 | + | |
| 454 | +table.admin-table { | |
| 455 | + @extend .table-bordered; | |
| 456 | + @extend .zebra-striped; | |
| 457 | + th { | |
| 458 | + border-color: #CCC; | |
| 459 | + border-bottom: 1px solid #bbb; | |
| 460 | + background:#eee; | |
| 461 | + background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
| 462 | + background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
| 463 | + background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
| 464 | + background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
| 465 | + } | |
| 466 | +} | ... | ... |
app/controllers/admin/users_controller.rb
| ... | ... | @@ -4,7 +4,9 @@ class Admin::UsersController < ApplicationController |
| 4 | 4 | before_filter :authenticate_admin! |
| 5 | 5 | |
| 6 | 6 | def index |
| 7 | - @admin_users = User.page(params[:page]) | |
| 7 | + @admin_users = User.scoped | |
| 8 | + @admin_users = @admin_users.filter(params[:filter]) | |
| 9 | + @admin_users = @admin_users.order("updated_at DESC").page(params[:page]) | |
| 8 | 10 | end |
| 9 | 11 | |
| 10 | 12 | def show |
| ... | ... | @@ -38,13 +40,31 @@ class Admin::UsersController < ApplicationController |
| 38 | 40 | @admin_user = User.find(params[:id]) |
| 39 | 41 | end |
| 40 | 42 | |
| 43 | + def block | |
| 44 | + @admin_user = User.find(params[:id]) | |
| 45 | + | |
| 46 | + if @admin_user.block | |
| 47 | + redirect_to :back, alert: "Successfully blocked" | |
| 48 | + else | |
| 49 | + redirect_to :back, alert: "Error occured. User was not blocked" | |
| 50 | + end | |
| 51 | + end | |
| 52 | + | |
| 53 | + def unblock | |
| 54 | + @admin_user = User.find(params[:id]) | |
| 55 | + | |
| 56 | + if @admin_user.update_attribute(:blocked, false) | |
| 57 | + redirect_to :back, alert: "Successfully unblocked" | |
| 58 | + else | |
| 59 | + redirect_to :back, alert: "Error occured. User was not unblocked" | |
| 60 | + end | |
| 61 | + end | |
| 62 | + | |
| 41 | 63 | def create |
| 42 | 64 | admin = params[:user].delete("admin") |
| 43 | - blocked = params[:user].delete("blocked") | |
| 44 | 65 | |
| 45 | 66 | @admin_user = User.new(params[:user]) |
| 46 | 67 | @admin_user.admin = (admin && admin.to_i > 0) |
| 47 | - @admin_user.blocked = blocked | |
| 48 | 68 | |
| 49 | 69 | respond_to do |format| |
| 50 | 70 | if @admin_user.save |
| ... | ... | @@ -59,7 +79,6 @@ class Admin::UsersController < ApplicationController |
| 59 | 79 | |
| 60 | 80 | def update |
| 61 | 81 | admin = params[:user].delete("admin") |
| 62 | - blocked = params[:user].delete("blocked") | |
| 63 | 82 | |
| 64 | 83 | if params[:user][:password].blank? |
| 65 | 84 | params[:user].delete(:password) |
| ... | ... | @@ -68,7 +87,6 @@ class Admin::UsersController < ApplicationController |
| 68 | 87 | |
| 69 | 88 | @admin_user = User.find(params[:id]) |
| 70 | 89 | @admin_user.admin = (admin && admin.to_i > 0) |
| 71 | - @admin_user.blocked = blocked | |
| 72 | 90 | |
| 73 | 91 | respond_to do |format| |
| 74 | 92 | if @admin_user.update_attributes(params[:user]) | ... | ... |
app/controllers/application_controller.rb
| 1 | 1 | class ApplicationController < ActionController::Base |
| 2 | 2 | before_filter :authenticate_user! |
| 3 | + before_filter :reject_blocked! | |
| 3 | 4 | before_filter :set_current_user_for_mailer |
| 4 | 5 | protect_from_forgery |
| 5 | 6 | helper_method :abilities, :can? |
| ... | ... | @@ -16,6 +17,14 @@ class ApplicationController < ActionController::Base |
| 16 | 17 | |
| 17 | 18 | protected |
| 18 | 19 | |
| 20 | + def reject_blocked! | |
| 21 | + if current_user && current_user.blocked | |
| 22 | + sign_out current_user | |
| 23 | + flash[:alert] = "Your account was blocked" | |
| 24 | + redirect_to new_user_session_path | |
| 25 | + end | |
| 26 | + end | |
| 27 | + | |
| 19 | 28 | def after_sign_in_path_for resource |
| 20 | 29 | if resource.is_a?(User) && resource.respond_to?(:blocked) && resource.blocked |
| 21 | 30 | sign_out resource | ... | ... |
app/models/user.rb
| ... | ... | @@ -48,7 +48,25 @@ class User < ActiveRecord::Base |
| 48 | 48 | |
| 49 | 49 | before_create :ensure_authentication_token |
| 50 | 50 | alias_attribute :private_token, :authentication_token |
| 51 | + | |
| 51 | 52 | scope :not_in_project, lambda { |project| where("id not in (:ids)", :ids => project.users.map(&:id) ) } |
| 53 | + scope :admins, where(:admin => true) | |
| 54 | + scope :blocked, where(:blocked => true) | |
| 55 | + scope :active, where(:blocked => false) | |
| 56 | + | |
| 57 | + def self.filter filter_name | |
| 58 | + case filter_name | |
| 59 | + when "admins"; self.admins | |
| 60 | + when "blocked"; self.blocked | |
| 61 | + when "wop"; self.without_projects | |
| 62 | + else | |
| 63 | + self.active | |
| 64 | + end | |
| 65 | + end | |
| 66 | + | |
| 67 | + def self.without_projects | |
| 68 | + where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') | |
| 69 | + end | |
| 52 | 70 | |
| 53 | 71 | def identifier |
| 54 | 72 | email.gsub /[@.]/, "_" |
| ... | ... | @@ -58,6 +76,7 @@ class User < ActiveRecord::Base |
| 58 | 76 | admin |
| 59 | 77 | end |
| 60 | 78 | |
| 79 | + | |
| 61 | 80 | def require_ssh_key? |
| 62 | 81 | keys.count == 0 |
| 63 | 82 | end |
| ... | ... | @@ -101,6 +120,17 @@ class User < ActiveRecord::Base |
| 101 | 120 | def project_ids |
| 102 | 121 | projects.map(&:id) |
| 103 | 122 | end |
| 123 | + | |
| 124 | + # Remove user from all projects and | |
| 125 | + # set blocked attribute to true | |
| 126 | + def block | |
| 127 | + users_projects.all.each do |membership| | |
| 128 | + return false unless membership.destroy | |
| 129 | + end | |
| 130 | + | |
| 131 | + self.blocked = true | |
| 132 | + save | |
| 133 | + end | |
| 104 | 134 | end |
| 105 | 135 | # == Schema Information |
| 106 | 136 | # | ... | ... |
app/views/admin/projects/index.html.haml
app/views/admin/projects/show.html.haml
| ... | ... | @@ -2,9 +2,8 @@ |
| 2 | 2 | = @admin_project.name |
| 3 | 3 | = link_to 'Edit', edit_admin_project_path(@admin_project), :class => "btn right small" |
| 4 | 4 | |
| 5 | -%hr | |
| 6 | - | |
| 7 | -%table.zebra-striped | |
| 5 | +%br | |
| 6 | +%table.zebra-striped.table-bordered | |
| 8 | 7 | %tr |
| 9 | 8 | %td |
| 10 | 9 | %b |
| ... | ... | @@ -29,47 +28,47 @@ |
| 29 | 28 | Description: |
| 30 | 29 | %td |
| 31 | 30 | = @admin_project.description |
| 31 | +%br | |
| 32 | +%h3 | |
| 33 | + Team | |
| 34 | + %small | |
| 35 | + (#{@admin_project.users_projects.count}) | |
| 36 | +%br | |
| 37 | +%table.zebra-striped.table-bordered | |
| 38 | + %thead | |
| 39 | + %tr | |
| 40 | + %th Name | |
| 41 | + %th Project Access | |
| 42 | + %th Repository Access | |
| 43 | + %th | |
| 32 | 44 | |
| 45 | + - @admin_project.users_projects.each do |tm| | |
| 46 | + %tr | |
| 47 | + %td | |
| 48 | + = link_to tm.user_name, admin_user_path(tm.user) | |
| 49 | + %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled | |
| 50 | + %td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small" | |
| 51 | + %td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn danger small" | |
| 33 | 52 | |
| 34 | -.span12 | |
| 35 | - | |
| 36 | - %h3 | |
| 37 | - Team | |
| 38 | - %small | |
| 39 | - (#{@admin_project.users_projects.count}) | |
| 40 | - | |
| 41 | - %hr | |
| 42 | - | |
| 43 | - %table.zebra-striped | |
| 53 | +%br | |
| 54 | +%h3 Add new team member | |
| 55 | +%br | |
| 56 | += form_tag team_update_admin_project_path(@admin_project), :class => "bulk_import", :method => :put do | |
| 57 | + %table.zebra-striped.table-bordered | |
| 44 | 58 | %thead |
| 45 | 59 | %tr |
| 46 | - %th Name | |
| 47 | - %th Project Access | |
| 48 | - %th Repository Access | |
| 49 | - %th | |
| 60 | + %th Users | |
| 61 | + %th Project Access: | |
| 50 | 62 | |
| 51 | - - @admin_project.users_projects.each do |tm| | |
| 52 | - %tr | |
| 53 | - %td | |
| 54 | - = link_to tm.user_name, admin_user_path(tm.user) | |
| 55 | - %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled | |
| 56 | - %td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small" | |
| 57 | - %td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn danger small" | |
| 58 | - | |
| 59 | - = form_tag team_update_admin_project_path(@admin_project), :class => "bulk_import", :method => :put do | |
| 60 | - %table | |
| 61 | - %thead | |
| 62 | - %tr | |
| 63 | - %th Users | |
| 64 | - %th Project Access: | |
| 65 | - %th Repo Access: | |
| 66 | - | |
| 67 | - %tr | |
| 68 | - %td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), :multiple => true | |
| 69 | - %td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select" | |
| 63 | + %tr | |
| 64 | + %td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), :multiple => true | |
| 65 | + %td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select" | |
| 70 | 66 | |
| 71 | - .actions | |
| 72 | - = submit_tag 'Add', :class => "btn primary" | |
| 67 | + %tr | |
| 68 | + %td= submit_tag 'Add', :class => "btn primary" | |
| 69 | + %td | |
| 70 | + Read more about project permissions | |
| 71 | + %strong= link_to "here", help_permissions_path, :class => "vlink" | |
| 73 | 72 | |
| 74 | 73 | :css |
| 75 | 74 | form select { | ... | ... |
app/views/admin/users/_form.html.haml
| ... | ... | @@ -6,41 +6,55 @@ |
| 6 | 6 | - @admin_user.errors.full_messages.each do |msg| |
| 7 | 7 | %li= msg |
| 8 | 8 | |
| 9 | - .clearfix | |
| 10 | - = f.label :name | |
| 11 | - .input= f.text_field :name | |
| 12 | - .clearfix | |
| 13 | - = f.label :email | |
| 14 | - .input= f.text_field :email | |
| 15 | - .clearfix | |
| 16 | - = f.label :password | |
| 17 | - .input= f.password_field :password | |
| 18 | - .clearfix | |
| 19 | - = f.label :password_confirmation | |
| 20 | - .input= f.password_field :password_confirmation | |
| 9 | + .row | |
| 10 | + .span6 | |
| 11 | + .clearfix | |
| 12 | + = f.label :name | |
| 13 | + .input | |
| 14 | + = f.text_field :name | |
| 15 | + %span.help-inline * requried | |
| 16 | + .clearfix | |
| 17 | + = f.label :email | |
| 18 | + .input | |
| 19 | + = f.text_field :email | |
| 20 | + %span.help-inline * requried | |
| 21 | + .clearfix | |
| 22 | + = f.label :password | |
| 23 | + .input= f.password_field :password | |
| 24 | + .clearfix | |
| 25 | + = f.label :password_confirmation | |
| 26 | + .input= f.password_field :password_confirmation | |
| 27 | + %hr | |
| 28 | + .clearfix | |
| 29 | + = f.label :skype | |
| 30 | + .input= f.text_field :skype | |
| 31 | + .clearfix | |
| 32 | + = f.label :linkedin | |
| 33 | + .input= f.text_field :linkedin | |
| 34 | + .clearfix | |
| 35 | + = f.label :twitter | |
| 36 | + .input= f.text_field :twitter | |
| 37 | + .span6 | |
| 38 | + .clearfix | |
| 39 | + = f.label :projects_limit | |
| 40 | + .input= f.text_field :projects_limit, :class => "small_input" | |
| 21 | 41 | |
| 22 | - .clearfix | |
| 23 | - = f.label :projects_limit | |
| 24 | - .input= f.text_field :projects_limit, :class => "small_input" | |
| 25 | - | |
| 26 | - .clearfix | |
| 27 | - = f.label :skype | |
| 28 | - .input= f.text_field :skype | |
| 29 | - .clearfix | |
| 30 | - = f.label :linkedin | |
| 31 | - .input= f.text_field :linkedin | |
| 32 | - .clearfix | |
| 33 | - = f.label :twitter | |
| 34 | - .input= f.text_field :twitter | |
| 35 | - %hr | |
| 36 | - .clearfix | |
| 37 | - = f.label :admin do | |
| 38 | - = f.check_box :admin | |
| 39 | - %span Administrator | |
| 40 | - .clearfix | |
| 41 | - = f.label :blocked do | |
| 42 | - = f.check_box :blocked | |
| 43 | - %span Blocked | |
| 42 | + .alert | |
| 43 | + .clearfix | |
| 44 | + %p Give user ability to manage application. | |
| 45 | + = f.label :admin, :class => "checkbox" do | |
| 46 | + = f.check_box :admin | |
| 47 | + %span Administrator | |
| 48 | + - unless @admin_user.new_record? | |
| 49 | + .alert.alert-error | |
| 50 | + - if @admin_user.blocked | |
| 51 | + %span | |
| 52 | + = link_to 'Unblock', unblock_admin_user_path(@admin_user), :method => :put, :class => "btn small" | |
| 53 | + This user is blocked and is not able to login GitLab | |
| 54 | + - else | |
| 55 | + %span | |
| 56 | + = link_to 'Block', block_admin_user_path(@admin_user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger" | |
| 57 | + Blocked user will removed from all projects & will not be able to login to GitLab. | |
| 44 | 58 | .actions |
| 45 | 59 | = f.submit 'Save', :class => "btn primary" |
| 46 | 60 | - if @admin_user.new_record? | ... | ... |
app/views/admin/users/index.html.haml
| ... | ... | @@ -2,15 +2,29 @@ |
| 2 | 2 | Users |
| 3 | 3 | = link_to 'New User', new_admin_user_path, :class => "btn small right" |
| 4 | 4 | %br |
| 5 | -%table.zebra-striped.table-bordered | |
| 5 | + | |
| 6 | +%ul.nav.nav-pills | |
| 7 | + %li{:class => "#{'active' unless params[:filter]}"} | |
| 8 | + = link_to "Active", admin_users_path | |
| 9 | + %li{:class => "#{'active' if params[:filter] == "admins"}"} | |
| 10 | + = link_to admin_users_path(:filter => "admins") do | |
| 11 | + Admins | |
| 12 | + %li{:class => "#{'active' if params[:filter] == "blocked"}"} | |
| 13 | + = link_to admin_users_path(:filter => "blocked") do | |
| 14 | + Blocked | |
| 15 | + %li{:class => "#{'active' if params[:filter] == "wop"}"} | |
| 16 | + = link_to admin_users_path(:filter => "wop") do | |
| 17 | + Without projects | |
| 18 | + | |
| 19 | +%table.admin-table | |
| 6 | 20 | %thead |
| 7 | 21 | %th Admin |
| 8 | 22 | %th Name |
| 9 | 23 | %th Email |
| 10 | 24 | %th Projects |
| 25 | + %th Edit | |
| 11 | 26 | %th Blocked |
| 12 | 27 | %th |
| 13 | - %th | |
| 14 | 28 | |
| 15 | 29 | - @admin_users.each do |user| |
| 16 | 30 | %tr |
| ... | ... | @@ -18,8 +32,12 @@ |
| 18 | 32 | %td= link_to user.name, [:admin, user] |
| 19 | 33 | %td= user.email |
| 20 | 34 | %td= user.users_projects.count |
| 21 | - %td= check_box_tag "blocked", 1, user.blocked, :disabled => :disabled | |
| 22 | 35 | %td= link_to 'Edit', edit_admin_user_path(user), :id => "edit_#{dom_id(user)}", :class => "btn small" |
| 23 | - %td= link_to 'Destroy', [:admin, user], :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger" | |
| 36 | + %td | |
| 37 | + - if user.blocked | |
| 38 | + = link_to 'Unblock', unblock_admin_user_path(user), :method => :put, :class => "btn small success" | |
| 39 | + - else | |
| 40 | + = link_to 'Block', block_admin_user_path(user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger" | |
| 41 | + %td= link_to 'Destroy', [:admin, user], :confirm => 'USER WILL BE REMOVED! Are you sure?', :method => :delete, :class => "btn small danger" | |
| 24 | 42 | |
| 25 | 43 | = paginate @admin_users, :theme => "admin" | ... | ... |
app/views/admin/users/show.html.haml
| 1 | 1 | %h3 |
| 2 | 2 | = @admin_user.name |
| 3 | + - if @admin_user.blocked | |
| 4 | + %small Blocked | |
| 5 | + - if @admin_user.admin | |
| 6 | + %small Administrator | |
| 3 | 7 | = link_to 'Edit', edit_admin_user_path(@admin_user), :class => "btn small right" |
| 4 | 8 | |
| 5 | -%hr | |
| 9 | +%br | |
| 6 | 10 | |
| 7 | -%table.zebra-striped | |
| 11 | +%table.zebra-striped.table-bordered | |
| 8 | 12 | %tr |
| 9 | 13 | %td |
| 10 | 14 | %b |
| ... | ... | @@ -49,41 +53,47 @@ |
| 49 | 53 | %td |
| 50 | 54 | = @admin_user.twitter |
| 51 | 55 | |
| 52 | -%h3 Projects | |
| 53 | -%hr | |
| 54 | - | |
| 55 | -%table.zebra-striped | |
| 56 | - %tr | |
| 57 | - %thead | |
| 58 | - %th Name | |
| 59 | - %th Project Access | |
| 60 | - %th Repository Access | |
| 61 | - %th | |
| 62 | - %th | |
| 63 | - | |
| 64 | - - @admin_user.users_projects.each do |tm| | |
| 65 | - - project = tm.project | |
| 66 | - %tr | |
| 67 | - %td= link_to project.name, admin_project_path(project) | |
| 68 | - %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled | |
| 69 | - %td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small" | |
| 70 | - %td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger" | |
| 71 | 56 | |
| 57 | +%br | |
| 58 | +%h3 Add User to Projects | |
| 59 | +%br | |
| 72 | 60 | = form_tag team_update_admin_user_path(@admin_user), :class => "bulk_import", :method => :put do |
| 73 | - %table | |
| 61 | + %table.table-bordered | |
| 74 | 62 | %thead |
| 75 | 63 | %tr |
| 76 | 64 | %th Projects |
| 77 | 65 | %th Project Access: |
| 78 | - %th Repo Access: | |
| 79 | 66 | |
| 80 | 67 | %tr |
| 81 | 68 | %td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), :multiple => true |
| 82 | 69 | %td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select" |
| 83 | 70 | |
| 84 | - .actions | |
| 85 | - = submit_tag 'Add', :class => "btn primary" | |
| 71 | + %tr | |
| 72 | + %td= submit_tag 'Add', :class => "btn primary" | |
| 73 | + %td | |
| 74 | + Read more about project permissions | |
| 75 | + %strong= link_to "here", help_permissions_path, :class => "vlink" | |
| 76 | +%br | |
| 77 | + | |
| 78 | +- if @admin_user.projects.present? | |
| 79 | + %h3 Projects | |
| 80 | + %br | |
| 86 | 81 | |
| 82 | + %table.zebra-striped.table-bordered | |
| 83 | + %tr | |
| 84 | + %thead | |
| 85 | + %th Name | |
| 86 | + %th Project Access | |
| 87 | + %th | |
| 88 | + %th | |
| 89 | + | |
| 90 | + - @admin_user.users_projects.each do |tm| | |
| 91 | + - project = tm.project | |
| 92 | + %tr | |
| 93 | + %td= link_to project.name, admin_project_path(project) | |
| 94 | + %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled | |
| 95 | + %td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small" | |
| 96 | + %td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger" | |
| 87 | 97 | |
| 88 | 98 | :css |
| 89 | 99 | form select { | ... | ... |
app/views/help/index.html.haml
app/views/layouts/admin.html.haml
| ... | ... | @@ -7,8 +7,8 @@ |
| 7 | 7 | .container |
| 8 | 8 | %nav.main_menu |
| 9 | 9 | = render "layouts/const_menu_links" |
| 10 | - = link_to "Users", admin_users_path, :class => controller.controller_name == "users" ? "current" : nil | |
| 11 | 10 | = link_to "Projects", admin_projects_path, :class => controller.controller_name == "projects" ? "current" : nil |
| 11 | + = link_to "Users", admin_users_path, :class => controller.controller_name == "users" ? "current" : nil | |
| 12 | 12 | = link_to "Emails", admin_emails_path, :class => controller.controller_name == "mailer" ? "current" : nil |
| 13 | 13 | = link_to "Resque", "/info/resque" |
| 14 | 14 | ... | ... |
config/routes.rb