Custom Authentication

Change Authentication Into Devise

  1. Install Camaleon CMS
  2. Install devise
    gem 'devise'
    rails g devise:install
    rails g devise blogger

    1. Change migration disabling existent attributes (email, timestamps), table name into CamaleonCms::User.table_name and change create_table into change_table, sample:
      class AddDeviseToBloggers < ActiveRecord::Migration
      def change
      change_table CamaleonCms::User.table_name do |t|
      ## Database authenticatable
      # t.string :email, null: false, default: "" ########## (commented)
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string :current_sign_in_ip
      t.string :last_sign_in_ip

      ## Confirmable
      # t.string :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      # Uncomment below if timestamps were not included in your original model.
      # t.timestamps null: false ########### (commented)
      end

      # add_index CamaleonCms::User.table_name, :email, unique: true ###### (commented)
      add_index CamaleonCms::User.table_name, :reset_password_token, unique: true
      # add_index CamaleonCms::User.table_name, :confirmation_token, unique: true
      # add_index CamaleonCms::User.table_name, :unlock_token, unique: true
      end
      end
    2. Modify Model blogger like this:
      class Blogger < ActiveRecord::Base
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable, :registerable,
      :recoverable, :rememberable, :trackable, :validatable

      #**** add this ******/
      include CamaleonCms::UserMethods
      alias_attribute :last_login_at, :last_sign_in_at
      self.table_name = PluginRoutes.static_system_info["cama_users_db_table"] || "#{PluginRoutes.static_system_info["db_prefix"]}users"
      default_scope {order(role: :asc)}
      validates :username, :presence => true
      alias_attribute :last_login_at, :last_sign_in_at
      #**** end ******/

      end
    3. Edit your config/system.json to add user_model, sample:
      {
      "share_sessions": true, // (boolean) share user sessions between subdomains of base_domain (only for users_share_sites = true)
      "default_user_role": "client", // default user role for all new users
      "users_share_sites": true, //(boolean) true: permit to share users between sites, false: All users are assigned for a unique site. (Only changed before installation)
      "db_prefix": "cama_", // prefix name for database tables
      "relative_url_root": "", // URL prefix, for example to get http://localhost:3000/blog/, this should be "blog"
      "hooks": {},
      "user_model": "Blogger" //******* (changed) ***************
      }
    4. Add this initializer which will overwrite routes and helpers
      # config/initializers/user_devise.rb
      Rails.application.config.to_prepare do
      CamaleonCms::SessionHelper.module_eval do
      def cama_current_user
      @cama_current_user ||= current_blogger.try(:decorate)
      end

      def cama_admin_login_path
      new_blogger_session_path
      end
      alias_method :cama_admin_login_url, :cama_admin_login_path

      def cama_admin_register_path
      new_blogger_registration_path
      end
      alias_method :cama_admin_register_url, :cama_admin_register_path

      def cama_admin_logout_path
      destroy_blogger_session_path
      end
      alias_method :cama_admin_logout_url, :cama_admin_logout_path
      end
      end
    5. Run Migration
      rake db:migrate
    6. Update password for your existent users (by console), sample:
      Cama::User.find_by_username('admin').update(password: 'admin123', password_confirmation: 'admin123')
    7. Configure your config/initializers/devise.rb to use username as login instead of email and accept GET method for logout
      config.sign_out_via = [:delete, :get]
      config.authentication_keys = [:username]
    8. Update your devise views to use username instead of email
    9. Edit application controller to accept username on submit login and define camaleon cms layout
      class ApplicationController < ActionController::Base
      # Prevent CSRF attacks by raising an exception.
      # For APIs, you may want to use :null_session instead.
      protect_from_forgery with: :exception

      ############ (added)
      before_action :configure_permitted_parameters, if: :devise_controller?
      layout :layout_by_resource, if: :devise_controller?

      def after_sign_in_path_for(resource)
      request.env['omniauth.origin'] || stored_location_for(resource) || cama_admin_url
      end

      protected
      def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :email])
      end

      def layout_by_resource
      'camaleon_cms/login'
      end
      ############ (end added)

      end
  3. Restart server
    Sample project here: https://github.com/camaleon-cms/devise-authentication

 


Custom Authentication Using My Model (for existent projects)

If you have already your users model, follow these steps:

  1. in your config/system.json
    "user_model": "MyUserModel"
  2. Create a migration with the following (You can remove some attributes you already have in your current model)
    add_column(CamaleonCms::User.table_name, :email, :string) unless column_exists?(CamaleonCms::User.table_name, :email)
    add_column(CamaleonCms::User.table_name, :username, :string) unless column_exists?(CamaleonCms::User.table_name, :username)
    add_column(CamaleonCms::User.table_name, :role, :string, default: 'client', index: true) unless column_exists?(CamaleonCms::User.table_name, :role)
    add_column(CamaleonCms::User.table_name, :parent_id, :integer) unless column_exists?(CamaleonCms::User.table_name, :parent_id)
    add_column(CamaleonCms::User.table_name, :site_id, :integer, index: true, default: -1) unless column_exists?(CamaleonCms::User.table_name, :site_id)
    add_column(CamaleonCms::User.table_name, :auth_token, :string) unless column_exists?(CamaleonCms::User.table_name, :auth_token)
    add_column CamaleonCms::User.table_name, :first_name, :string unless column_exists?(CamaleonCms::User.table_name, :first_name)
    add_column CamaleonCms::User.table_name, :last_name, :string unless column_exists?(CamaleonCms::User.table_name, :last_name)
    add_column CamaleonCms::User.table_name, :last_login_at, :datetime unless column_exists?(CamaleonCms::User.table_name, :last_login_at)
  3. Modify your current model to add this:
    include CamaleonCms::UserMethods
    Note:  Also, you can add alias_attribute for existent attributes in your current model, sample:
    alias_attribute :username, :login
    alias_attribute :last_login_at, :last_sign_in_at
  4. Run migration
    rake db:migrate

    Note: You'll need to set the role "admin" to your admin users (only if you have already users) OR you can create one by console:
    Cama::Site.first.users.admin_scope.create({email: 'admin@local.com', username: 'admin', password: 'admin123', password_confirmation: 'admin123', first_name: 'Administrator'})


  5. Create an initializer config/initializers/custom_login.rb to update urls and overwrite helpers
    module CamaleonCms::SessionHelper 
    def cama_current_user
    my_current_user.try(:decorate)
    end

    def cama_admin_login_path
    my_custom_login_path
    end
    alias_method :cama_admin_login_url, :cama_admin_login_path

    def cama_admin_register_path
    my_custom_signup_path
    end
    alias_method :cama_admin_register_url, :cama_admin_register_path

    def cama_admin_logout_path
    my_custom_logout_path
    end
    alias_method :cama_admin_logout_url, :cama_admin_logout_path
    end
  6. restart server