Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Fri, Aug 8, 8:44 PM
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 457b401..ed2c116 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -1,130 +1,130 @@
class Admin::UsersController < Admin::BaseController
before_action :fetch_user, only: [:show, :edit, :update, :ban, :unban,
:grant_admin, :revoke_admin]
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_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)
+ if @user.admin? && @user.update_attributes_and_password(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)
+ render :edit
else
flash[:error] = "User is #{@user.user_type} and thus accepts no updates"
- redirect_to admin_user_path(@user)
+ render :edit
end
end
# PATCH /admin/users/1/ban
def ban
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
if @user.unban
flash[:success] = 'User enabled'
else
flash[:error] = 'User NOT enabled'
end
redirect_to admin_users_path
end
# PATCH /admin/users/1/revoke_admin
def revoke_admin
if @user.update_attribute(:moderator, false)
flash[:success] = 'User is no longer an admin'
else
flash[:error] = 'Admin rights were NOT revoked'
end
redirect_to admin_users_path
end
# PATCH /admin/users/1/grant_admin
def grant_admin
if @user.update_attribute(:moderator, true)
flash[:success] = 'User is now an admin'
else
flash[:error] = 'Admin rights were NOT granted'
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 5947f71..0fdd3e2 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,147 +1,161 @@
class User < ActiveRecord::Base
establish_connection ARCHIVING_CONF
attr_accessor :password, :retype_password
serialize :temp_hosts, JSON
has_many :ownerships
has_many :hosts, through: :ownerships, inverse_of: :users
has_many :invitations
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?
before_create :create_token
# 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
# Initializes a user token which will be used for API access
def create_token(opts = {})
self.token = Digest::SHA256.hexdigest(
Time.now.to_s + Rails.application.secrets.salt + email
)
save if opts[:save] == true
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
hosts.each do |host|
if host.client.present?
host.disable_jobs_and_lock
else
host.block
end
end
end
# Marks a user as enabled
def unban
self.enabled = true
save
end
+ # Updates the user and handles the password field accordingly
+ #
+ # @param attrs[Hash] the desired attributes
+ def update_attributes_and_password(attrs)
+ self.assign_attributes(attrs)
+ self.valid?
+ if self.password.present? && confirm_passwords
+ self.password_hash = Digest::SHA256.hexdigest(self.password + Rails.application.secrets.salt)
+ end
+ if self.errors.empty?
+ self.save
+ end
+ 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
# Determines if a vima user needs to update his hosts' list
#
# @return [Boolean]
def refetch_hosts?
return false unless vima?
return true if hosts_updated_at.nil?
hosts_updated_at < Archiving.settings[:skip_host_fetch_time_period].ago
end
# Determines if a user has admin access to archiving or not
#
# @return [Boolean]
def has_admin_access?
admin? || moderator?
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/_form.html.erb b/app/views/admin/users/_form.html.erb
index f37c60c..b31a67f 100644
--- a/app/views/admin/users/_form.html.erb
+++ b/app/views/admin/users/_form.html.erb
@@ -1,15 +1,15 @@
<%= bootstrap_form_for(@user, url: url, method: method, layout: :horizontal,
label_col: 'col-xs-3', control_col: 'col-xs-8') do |f| %>
<%= f.text_field :username, required: true %>
- <%= f.password_field :password, required: true %>
- <%= f.password_field :retype_password, required: true %>
+ <%= f.password_field :password, required: new_user %>
+ <%= f.password_field :retype_password, required: new_user %>
<%= f.email_field :email, required: true %>
<div class="form-group">
<div class="col-xs-offset-8 col-xs-3">
<%= f.submit class: 'btn btn-success' %>
</div>
</div>
<% end %>
<%= link_to 'Cancel', admin_users_path, class: 'btn btn-danger', role: 'button' %>
diff --git a/app/views/admin/users/edit.html.erb b/app/views/admin/users/edit.html.erb
index ad97e64..e04ffe3 100644
--- a/app/views/admin/users/edit.html.erb
+++ b/app/views/admin/users/edit.html.erb
@@ -1,13 +1,14 @@
<%= render partial: 'header' %>
<div class="row">
<div class="col-xs-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3>Edit Admin</h3>
- <%= render partial: 'form', locals: { url: admin_user_path(@user), method: :patch } %>
+ <%= render partial: 'form', locals: { url: admin_user_path(@user), method: :patch,
+ new_user: false } %>
</div>
</div>
</div>
</div>
diff --git a/app/views/admin/users/new.html.erb b/app/views/admin/users/new.html.erb
index 2cca3a3..c2e462d 100644
--- a/app/views/admin/users/new.html.erb
+++ b/app/views/admin/users/new.html.erb
@@ -1,13 +1,14 @@
<%= 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', locals: { url: admin_users_path, method: :post } %>
+ <%= render partial: 'form', locals: { url: admin_users_path, method: :post,
+ new_user: true } %>
</div>
</div>
</div>
</div>

Event Timeline