2
\$\begingroup\$

previusly I make a post for Session Logic for User Verification in Rails Migration. Now the improvement version following advice of the comments is here.

The problem was the use of `` for executing in shell on a RoR application when making the log in. I remove it and change for system method.

module Shared
  extend ActiveSupport::Concern

  def password_regex
    /
      \A # The string must
        (?=.*[a-z]) # contain at least 1 lowercase alphabetical character
        (?=.*[A-Z]) # contain at least 1 uppercase alphabetical character
        (?=.*[0-9]) # contain at least 1 numeric character
        (?=.*[!@#$%^&*]) # contain at least one special character
        .{8,}   # Be eight characters or longer
      \z
    /x
  end
end
class SessionsController < ApplicationController
  include Shared

  layout 'modal-wrapper'

  def new
    @user = User.new
  end

  def create
    @user = User.find_by(username: username)

    if valid_params?(password)
      session[:user_id] = @user.id
      redirect_to root_path
    else
      flash[:error] = 'Invalid user or password.'
      redirect_to login_path
    end
  end

  private

  def legacy_authenticate(pass_plain)
    php_file = 'app/scripts/legacy_authenticate.php'

    if pass_plain =~ password_regex
      system('php', php_file, pass_plain, @user.password_php)
    else
      false
    end
  end

  def valid_params?(pass_plain)
    if @user&.password_php
      legacy_authenticate(pass_plain)
    elsif @user&.password_digest
      @user.authenticate(pass_plain)
    else
      false
    end
  end

  def username
    params[:user][:username]
  end

  def password
    params[:user][:password]
  end
end

legacy_authenticate.php

$password = $argv[1];
$hased_password = $argv[2];

if (password_verify($password, $hased_password)) {
  exit(0);
} else {
  exit(1);
}

the form that call the method

<%= form_for(@user, html: { class: 'log-form' }) do |f| %>
  <%= f.text_field :firstname, placeholder: 'First Name' %>
  <%= f.text_field :lastname, placeholder: 'Last Name' %>
  <%= f.text_field :username, placeholder: 'Username', required: true %>
  <%= f.email_field :email, placeholder: 'Email', required: true %>
  <%= f.password_field :password, placeholder: 'Password', required: true %>
  <%= f.password_field :password_confirmation, placeholder: 'Confirm Password', required: true %>
  <%= f.submit 'Log Up', class: 'btn btn-submit' %>
<% end %>

the unit test with 0 failures

require 'test_helper'

class SessionsControllerTest < ActionDispatch::IntegrationTest
  setup do
    @user = users(:one)
  end

  test 'should get new' do
    get login_path
    assert_response :success
  end

  test 'should login' do
    post login_path, params: { user: { username: @user.username, password: 'MyString#123' } }
    assert_response :redirect
    assert_redirected_to root_path
  end

  test 'should logout' do
    delete logout_path
    assert_response :redirect
    assert_redirected_to root_path
  end
end

and the tested data yml file

one:
  username: MyString
  email: [email protected]
  password_php: $2y$10$FYJ5PvFRPaFWWZPhFYlxEuiETZwlk5PmoehlOiR93r3.4M3gU8QVy
  password_digest: <%= BCrypt::Password.create('MyString#123') %>

Fell free to check the other post, all the modification were following the advice of J_H including the writing of this post

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Regarding the PHP part, you can make it a bit simpler

$result = password_verify($password, $hased_password);
exit((int)$result);
\$\endgroup\$
2
  • \$\begingroup\$ the int before the variable change the data type? \$\endgroup\$ Commented Jan 29, 2024 at 18:06
  • 1
    \$\begingroup\$ yes, it casts a variable to integer type \$\endgroup\$ Commented Jan 30, 2024 at 5:47

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.