diff --git a/app/models/user.rb b/app/models/user.rb index 8bf783d..7eff2b7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,123 +1,131 @@ 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? # 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 + self.token = Digest::SHA256.hexdigest( + Time.now.to_s + Rails.application.secrets.salt + email + ) + save + 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 # 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 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/db/migrate/20160418163337_add_token_to_user.rb b/db/migrate/20160418163337_add_token_to_user.rb new file mode 100644 index 0000000..b97b1f4 --- /dev/null +++ b/db/migrate/20160418163337_add_token_to_user.rb @@ -0,0 +1,7 @@ +class AddTokenToUser < ActiveRecord::Migration + def change + add_column :users, :token, :string + + add_index :users, :token + end +end diff --git a/db/schema.rb b/db/schema.rb index 69301cf..68b41a6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,138 +1,140 @@ # encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # # Note that this schema.rb definition is the authoritative source for your # database schema. If you need to create the application database on another # system, you should be using db:schema:load, not running all the migrations # from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160404163444) do +ActiveRecord::Schema.define(version: 20160418163337) do create_table "configuration_settings", force: true do |t| t.string "job", default: "{}" t.string "client", default: "{}" t.datetime "created_at" t.datetime "updated_at" t.string "pool", default: "{}" end create_table "faqs", force: true do |t| t.string "title" t.text "body" t.integer "priority", default: 0 t.datetime "created_at" t.datetime "updated_at" end create_table "filesets", force: true do |t| t.string "name" t.integer "host_id" t.text "exclude_directions" t.text "include_directions" t.datetime "created_at" t.datetime "updated_at" end add_index "filesets", ["host_id"], name: "index_filesets_on_host_id", using: :btree create_table "hosts", force: true do |t| t.binary "name", limit: 255, null: false t.binary "fqdn", limit: 255, null: false t.integer "port", null: false t.integer "file_retention", null: false t.integer "job_retention", null: false t.datetime "created_at" t.datetime "updated_at" t.string "password" t.boolean "baculized", default: false, null: false t.datetime "baculized_at" t.integer "status", limit: 1, default: 0 t.integer "client_id" t.boolean "verified", default: false t.datetime "verified_at" t.integer "verifier_id" t.string "job_retention_period_type" t.string "file_retention_period_type" t.integer "origin", limit: 1 t.string "email_recipients", default: "[]" t.integer "quota", limit: 8, default: 104857600 end add_index "hosts", ["name"], name: "index_hosts_on_name", unique: true, length: {"name"=>128}, using: :btree create_table "invitations", force: true do |t| t.integer "user_id" t.integer "host_id" t.string "verification_code" t.datetime "created_at" t.datetime "updated_at" end add_index "invitations", ["user_id", "verification_code"], name: "index_invitations_on_user_id_and_verification_code", using: :btree create_table "job_templates", force: true do |t| t.string "name", null: false t.integer "job_type", limit: 1 t.integer "host_id" t.integer "fileset_id" t.integer "schedule_id" t.datetime "created_at" t.datetime "updated_at" t.boolean "enabled", default: false t.binary "restore_location" t.boolean "baculized", default: false t.datetime "baculized_at" t.string "client_before_run_file" t.string "client_after_run_file" end create_table "ownerships", force: true do |t| t.integer "user_id" t.integer "host_id" t.datetime "created_at" t.datetime "updated_at" end create_table "schedule_runs", force: true do |t| t.integer "schedule_id" t.integer "level", limit: 1 t.string "month" t.string "day" t.string "time" t.datetime "created_at" t.datetime "updated_at" end add_index "schedule_runs", ["schedule_id"], name: "index_schedule_runs_on_schedule_id", using: :btree create_table "schedules", force: true do |t| t.string "name" t.string "runs" t.integer "host_id" end add_index "schedules", ["host_id"], name: "index_schedules_on_host_id", using: :btree create_table "users", force: true do |t| t.string "username", null: false t.string "email" t.integer "user_type", limit: 1, null: false t.boolean "enabled", default: false t.datetime "created_at" t.datetime "updated_at" t.string "identifier" t.string "password_hash" t.datetime "login_at" t.datetime "hosts_updated_at" t.string "temp_hosts", default: "[]" + t.string "token" end add_index "users", ["identifier"], name: "index_users_on_identifier", using: :btree add_index "users", ["password_hash"], name: "index_users_on_password_hash", using: :btree + add_index "users", ["token"], name: "index_arch.users_on_token", using: :btree end