Page Menu
Home
GRNET
Search
Configure Global Search
Log In
Files
F1615018
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Mar 21, 2:14 PM
Size
18 KB
Mime Type
text/x-diff
Expires
Mon, Mar 23, 2:14 PM (1 d, 16 h)
Engine
blob
Format
Raw Data
Handle
354263
Attached To
rARCHIVING archiving
View Options
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 5752c2c..4d9137d 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -1,71 +1,106 @@
class Admin::UsersController < Admin::BaseController
+ before_action :fetch_user, only: [:show, :edit, :update, :ban, :unban]
+ before_action :editable_users_only, only: [:edit, :update]
+
# GET /admin/users
def index
@baculized_host_names = Hash.new { |h, k| h[k] = [] }
@non_baculized_host_names = Hash.new { |h, k| h[k] = [] }
@unverified_host_names = Hash.new { |h, k| h[k] = [] }
@users = User.all.includes(:hosts)
@users = @users.admin if params[:type] == 'admin'
@users = @users.vima if params[:type] == 'vima'
+ @users = @users.institutional if params[:type] == 'institutional'
@users.each do |user|
user.hosts.each do |host|
if host.deployed? || host.updated? || host.dispatched? || host.for_removal?
@baculized_host_names[user.id] << host.name
else
@non_baculized_host_names[user.id] << host.name
@unverified_host_names[user.id] << host.name if !host.verified?
end
end
end
end
# GET /admin/users/new
def new
- @user = User.new
+ @user = User.new(user_type: :admin)
end
# POST /admin/users
def create
@user = User.new(fetch_params)
@user.user_type = :admin
if @user.add_password(@user.password)
flash[:success] = 'User created'
redirect_to admin_users_path
else
flash[:error] = 'User was not created'
render 'new'
end
end
+ # GET /admin/users/1
+ def show
+ end
+
+ # GET /admin/users/1/edit
+ def edit
+ end
+
+ # PATCH /admin/users/1/update
+ def update
+ if @user.admin? && @user.update_attributes(fetch_params)
+ flash[:success] = 'User updated'
+ redirect_to admin_user_path(@user)
+ elsif @user.admin?
+ flash[:error] = 'User not updated'
+ redirect_to edit_admin_user_path(@user)
+ else
+ flash[:error] = "User is #{@user.user_type} and thus accepts no updates"
+ redirect_to admin_user_path(@user)
+ end
+ end
+
# PATCH /admin/users/1/ban
def ban
- @user = User.find(params[:id])
if @user.ban
flash[:success] = 'User banned'
else
flash[:error] = 'User NOT banned'
end
redirect_to admin_users_path
end
# PATCH /admin/users/1/unban
def unban
- @user = User.find(params[:id])
if @user.unban
flash[:success] = 'User enabled'
else
flash[:error] = 'User NOT enabled'
end
redirect_to admin_users_path
end
private
def fetch_params
params.require(:user).permit(:username, :email, :password, :retype_password)
end
+
+ def fetch_user
+ @user = User.find(params[:id])
+ end
+
+ def editable_users_only
+ return if @user.editable?
+
+ flash[:error] = "User #{@user.username} is not editable"
+ redirect_to admin_users_path
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 7fc1c97..614d625 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,101 +1,109 @@
class User < ActiveRecord::Base
attr_accessor :password, :retype_password
has_many :ownerships
has_many :hosts, through: :ownerships, inverse_of: :users
enum user_type: { institutional: 0, vima: 1, okeanos: 2, admin: 3 }
validates :user_type, presence: true
validates :username, presence: true, uniqueness: { scope: :user_type }
validates :email, presence: true, uniqueness: { scope: :user_type }
before_create :confirm_passwords, if: :admin?
# Returns an admin user with the given password
#
# @param username[String] username from user input
# @param a_password[String] password from user input
#
# @return [User] the admin user or nil
def self.fetch_admin_with_password(username, a_password)
hashed_pass = Digest::SHA256.hexdigest(a_password + Rails.application.secrets.salt)
admin = User.admin.find_by_username_and_password_hash(username, hashed_pass)
admin
end
# Composes the user's display name from the user's username and email
#
# @return [String]
def display_name
"#{username} <#{email}>"
end
# Determines if the user must select hosts from a list or enter their
# FQDN manually
#
# @return [Boolean]
def needs_host_list?
vima? || okeanos?
end
+ # Determines if the user is editable or not.
+ # Editable users are only admin users, all others come from 3rd party authorization
+ #
+ # @return [Boolean]
+ def editable?
+ admin?
+ end
+
# Marks a user as not enabled
def ban
self.enabled = false
save
end
# Marks a user as enabled
def unban
self.enabled = true
save
end
# Stores a hashed password as a password_hash
#
# @param a_password[String] the user submitted password
#
# @return [Boolean] the save exit status
def add_password(a_password)
self.password_hash = Digest::SHA256.hexdigest(a_password + Rails.application.secrets.salt)
self.save
end
# Fetches the user's unverified hosts
#
# @return [Array] of Strings containing the hosts' names
def unverified_hosts
hosts.unverified.pluck(:name)
end
# Fetches the user's hosts that are being backed up by bacula
#
# @return [Array] of Strings configuration the host's names
def baculized_hosts
hosts.in_bacula.pluck(:name)
end
# Fetches the user's hosts that are NOT being backed up by bacula
#
# @return [Array] of Strings configuration the host's names
def non_baculized_hosts
hosts.not_baculized.pluck(:name)
end
private
def confirm_passwords
if password.blank?
self.errors.add(:password, 'Must give a password')
return false
end
if password != retype_password
self.errors.add(:password, 'Passwords mismatch')
self.errors.add(:retype_password, 'Passwords mismatch')
return false
end
true
end
end
diff --git a/app/views/admin/users/_header.html.erb b/app/views/admin/users/_header.html.erb
new file mode 100644
index 0000000..a332735
--- /dev/null
+++ b/app/views/admin/users/_header.html.erb
@@ -0,0 +1,5 @@
+<%= breadcrumb_with Admin: admin_path,
+ Users: admin_users_path,
+ @user.user_type.capitalize => admin_users_path(type: @user.user_type),
+ (@user.username || 'New') => @user.persisted? ? admin_user_path(@user):''
+ %>
diff --git a/app/views/admin/users/_user.html.erb b/app/views/admin/users/_user.html.erb
index 20a857d..2ca9474 100644
--- a/app/views/admin/users/_user.html.erb
+++ b/app/views/admin/users/_user.html.erb
@@ -1,25 +1,35 @@
<tr>
- <td>#<%= user.id %></td>
- <td><%= user.username %></td>
+ <td><%= link_to "##{user.id}", admin_user_path(user) %></td>
+ <td><%= link_to user.username, admin_user_path(user) %></td>
<td><%= user.email %></td>
<td><%= user.user_type %></td>
<td><%= I18n.l(user.created_at, format: :short) %></td>
<td><%= inline_list @baculized_host_names[user.id] %></td>
<td><%= inline_list @unverified_host_names[user.id] %></td>
<td><%= inline_list @non_baculized_host_names[user.id] %></td>
<td>
+ <%= link_to admin_user_path(user) do %>
+ <label class="glyphicon glyphicon-eye-open text-primary" alt="show"></label>
+ <% end %>
+ <% if user.editable? %>
+ <%= link_to edit_admin_user_path(user) do %>
+ <label class="glyphicon glyphicon-edit text-primary" alt="show"></label>
+ <% end %>
+ <% end %>
+ </td>
+ <td>
<% if user.enabled? %>
<%= link_to ban_admin_user_path(user), method: :patch, class: 'btn btn-default',
- data: { confirm: 'User will be banned' } do %>
- <label class="glyphicon glyphicon-remove text-danger"></label>
+ data: { confirm: "User #{user.username} will be banned" } do %>
+ <label class="glyphicon glyphicon-ban-circle text-danger"></label>
Ban
<% end %>
<% else %>
<%= link_to unban_admin_user_path(user), method: :patch, class: 'btn btn-default',
- data: { confirm: 'User will be unbanned' } do %>
- <label class="glyphicon glyphicon-ok text-success"></label>
+ data: { confirm: "User #{user.username} will be unbanned" } do %>
+ <label class="glyphicon glyphicon-ok-circle text-success"></label>
Unban
<% end %>
<% end %>
</td>
</tr>
diff --git a/app/views/admin/users/new.html.erb b/app/views/admin/users/edit.html.erb
similarity index 76%
copy from app/views/admin/users/new.html.erb
copy to app/views/admin/users/edit.html.erb
index 010faa0..52f80b6 100644
--- a/app/views/admin/users/new.html.erb
+++ b/app/views/admin/users/edit.html.erb
@@ -1,11 +1,13 @@
+<%= render partial: 'header' %>
+
<div class="row">
<div class="col-xs-4">
<div class="panel panel-default">
<div class="panel-heading">
- <h3>New Admin</h3>
+ <h3>Edit Admin</h3>
<%= render partial: 'form' %>
</div>
</div>
</div>
</div>
diff --git a/app/views/admin/users/index.html.erb b/app/views/admin/users/index.html.erb
index d0fa88c..1f06a17 100644
--- a/app/views/admin/users/index.html.erb
+++ b/app/views/admin/users/index.html.erb
@@ -1,34 +1,35 @@
<div class="row right">
<%= link_to new_admin_user_path, class: "btn btn-default", role: "button" do %>
<label class="glyphicon glyphicon-plus text-primary"></label>
New Admin
<% end %>
</div>
<h1>Users</h1>
<div class="row">
<div class="col-xs-12">
<div class="table-responsive">
<table class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>id</th>
- <th>username</th>
- <th>email</th>
- <th>user type</th>
- <th>created at</th>
- <th>clients</th>
- <th>unverified hosts</th>
- <th>pending hosts</th>
- <th>actions</th>
+ <th>Username</th>
+ <th>Email</th>
+ <th>User type</th>
+ <th>Created at</th>
+ <th>Clients</th>
+ <th>Unverified hosts</th>
+ <th>Pending hosts</th>
+ <th>Actions</th>
+ <th>Ban</th>
</tr>
</thead>
<tbody>
<%= render partial: 'user', collection: @users %>
</tbody>
</table>
</div>
</div>
</div>
diff --git a/app/views/admin/users/new.html.erb b/app/views/admin/users/new.html.erb
index 010faa0..5427af3 100644
--- a/app/views/admin/users/new.html.erb
+++ b/app/views/admin/users/new.html.erb
@@ -1,11 +1,13 @@
+<%= render partial: 'header' %>
+
<div class="row">
<div class="col-xs-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3>New Admin</h3>
<%= render partial: 'form' %>
</div>
</div>
</div>
</div>
diff --git a/app/views/admin/users/show.html.erb b/app/views/admin/users/show.html.erb
new file mode 100644
index 0000000..6c637a6
--- /dev/null
+++ b/app/views/admin/users/show.html.erb
@@ -0,0 +1,71 @@
+<%= render partial: 'header' %>
+
+<div class="col-xs-5">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h2>User details</h2>
+ </div>
+
+ <br/>
+
+ <div class="table-responsive">
+ <table class="table table-striped table-bordered table-condensed">
+ <tr>
+ <td><b>Username</b></td>
+ <td><%= @user.username %></td>
+ </tr>
+ <tr>
+ <td><b>Email</b></td>
+ <td><%= @user.email %></td>
+ </tr>
+ <tr>
+ <td><b>User Type</b></td>
+ <td><%= @user.user_type %></td>
+ </tr>
+ <tr>
+ <td><b>Created At</b></td>
+ <td><%= I18n.l(@user.created_at, format: :short) rescue '-' %></td>
+ </tr>
+ <tr>
+ <td><b>Login At</b></td>
+ <td><%= I18n.l(@user.login_at, format: :short) rescue '-' %></td>
+ </tr>
+ <tr>
+ <td><b>Clients</b></td>
+ <td><%= inline_list @user.baculized_hosts %></td>
+ </tr>
+ <tr>
+ <td><b>Pending Hosts</b></td>
+ <td><%= inline_list @user.non_baculized_hosts %></td>
+ </tr>
+ <% if @user.institutional? %>
+ <tr>
+ <td><b>Unverified Hosts</b></td>
+ <td><%= inline_list @user.unverified_hosts %></td>
+ </tr>
+ <% end %>
+ </table>
+ </div>
+ </div>
+ <% if @user.editable? %>
+ <%= link_to edit_admin_user_path(@user), class: 'btn btn-primary' do %>
+ <label class="glyphicon glyphicon-ok-edit text-success"></label>
+ Edit User
+ <% end %>
+ <% end %>
+ <% if @user.enabled? %>
+ <%= link_to ban_admin_user_path(@user), method: :patch, class: 'btn btn-default',
+ data: { confirm: "User #{@user.username} will be banned" } do %>
+ <label class="glyphicon glyphicon-ban-circle text-danger"></label>
+ Ban User
+ <% end %>
+ <% else %>
+ <%= link_to unban_admin_user_path(@user), method: :patch, class: 'btn btn-default',
+ data: { confirm: "User #{@user.username} will be unbanned" } do %>
+ <label class="glyphicon glyphicon-ok-circle text-success"></label>
+ Unban User
+ <% end %>
+ <% end %>
+
+ <%= link_to 'Back to users', admin_users_path, class: 'right' %>
+</div>
diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb
index ca41736..bfacf33 100644
--- a/app/views/shared/_nav.html.erb
+++ b/app/views/shared/_nav.html.erb
@@ -1,73 +1,76 @@
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="logo">
<%= link_to root_path do %>
<p><b>GRNET NOC</b></p>
<p>Archiving</p>
<% end %>
</li>
<% if current_user %>
<%= content_tag(:li, active_class(clients_path, true)) do %>
<%= link_to 'Clients', clients_path %>
<% end %>
<li><%= link_to current_user.username, '#' %></li>
<% end %>
</ul>
<% if current_user %>
<ul class="nav navbar-nav navbar-right">
<li>
<%= link_to logout_path do %>
<label class="glyphicon glyphicon-log-out"></label>
Logout
<% end %>
</li>
</ul>
<% end %>
<% if current_user.try(:admin?) %>
<ul class="nav navbar-nav navbar-right">
<%= content_tag(:li, active_class(admin_path)) do %>
<%= link_to 'Admin', admin_path %>
<% end %>
<%= content_tag(:li, active_class(admin_clients_path, true)) do %>
<%= link_to 'Clients', admin_clients_path %>
<% end %>
<%= content_tag(:li, active_class(unverified_admin_hosts_path, true)) do %>
<%= link_to 'Hosts', unverified_admin_hosts_path %>
<% end %>
<%= content_tag(:li, { class: "dropdown #{active_class(admin_users_path)[:class]}" }) do %>
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Users <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>
<%= link_to 'All Users', admin_users_path %>
</li>
<li class="divider"></li>
<li>
<%= link_to 'ViMa Users', admin_users_path(type: :vima) %>
</li>
<li>
+ <%= link_to 'Institutional Users', admin_users_path(type: :institutional) %>
+ </li>
+ <li>
<%= link_to 'Admins', admin_users_path(type: :admin) %>
</li>
<li>
</ul>
<% end %>
<%= content_tag(:li, active_class(admin_settings_path)) do %>
<%= link_to 'Settings', admin_settings_path %>
<% end %>
</ul>
<% end %>
</div><!--/.nav-collapse -->
</div>
</nav>
diff --git a/config/routes.rb b/config/routes.rb
index 7da6c85..91eb988 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,82 +1,82 @@
Rails.application.routes.draw do
root 'application#index'
post 'grnet' => 'application#grnet'
get 'institutional' => 'application#institutional'
match 'vima', to: 'application#vima', :via => [:get, :post]
get 'logout' => 'application#logout'
resources :clients, only: [:index, :show] do
member do
get :jobs
get :logs
get :stats
post :stats
get :users
get :restore
post :run_restore
end
collection do
post :index
end
end
resources :hosts, only: [:new, :create, :show, :edit, :update, :destroy] do
member do
post :submit_config
post :disable
delete :revoke
end
resources :jobs, only: [:new, :create, :show, :edit, :update, :destroy] do
member do
patch :toggle_enable
post :backup_now
end
end
resources :filesets, only: [:show, :new, :create, :destroy]
resources :schedules, only: [:show, :new, :edit, :create, :update, :destroy]
end
namespace :admin do
match '/', to: 'base#index', via: [:get, :post]
get '/login' => 'base#login', as: :login
resources :settings, only: [:index, :new, :create, :edit, :update] do
member do
delete :reset
end
end
resources :clients, only: [:index, :show] do
member do
get :jobs
get :logs
get :stats
post :stats
get :configuration
post :disable
delete :revoke
end
end
resources :hosts, only: [:show] do
collection do
get :unverified
end
member do
post :verify
end
end
- resources :users, only: [:index, :new, :create] do
+ resources :users, only: [:index, :new, :create, :show, :edit, :update] do
member do
patch :ban
patch :unban
end
end
end
end
Event Timeline
Log In to Comment