confronting with Filter chain halted as :require_no_authentication rendered or redirected with rails 4 when iam trying to reset the password - ruby-on-rails-4.2

this is my home_controller.rb
class HomeController < ApplicationController
def index
end
end
my routes.rb file
devise_for :users ,:controllers => {:sessions => "users/sessions"}
devise_scope :user do
root :to =>"users/sessions#new"
end
my development.rb file
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.delivery_method = :smtp
config.cache_classes = false
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
user_name:"ajeet.soni10#gmail.com",
password: "6473eyre",
authentication: "plain",
enable_starttls_auto: true,
}`
`
so iam using url:-http://localhost:3000//signin it shows me the log in page user can singup usually but when user wants to reset his password
by clicking on forgot password the whole page is halted with a redirect loop

there was a problem in routes.rb file i rectified that file and it worked
Login::Application.routes.draw do
resources :pets
#devise_for :users
devise_for :users ,:controllers => {:sessions => "users/sessions"}
devise_scope :user do
root :to =>"users/sessions#new"
end

Related

Codeigniter 4 allow user to login using either username or email

Currently I have a login feature and I have only set user can login using username. How do I make it for user to login either using username or email and check with my database if username exist when users login with their username and if email exist when users login with their email? Below is my current code:
Controller
public function login()
{
$data = [];
helper(['form']);
$validation = \Config\Services::validation();
if($this->request->getMethod() == 'post'){
//validations
$rules = [
'username' => 'required',
'password' => 'required|validateUser[username, password]'
];
$errors = [
'password' => [
'validateUser' => 'Username or Password don\'t match'
]
];
if(!$this->validate($rules, $errors)){
$data['validation'] = $this->validator;
}else{
$model = new AccountModel();
$user = $model->where('username', $this->request->getVar('username'))
->first();
$this->setUserSession($user);
return redirect()->to('/account/profile');
}
}
echo view('templates/header', $data);
echo view('account/login');
echo view('templates/footer');
}
My validation rules
<?php
namespace App\Validation;
use App\Models\AccountModel;
class UserRules
{
public function validateUser(string $str, string $fields, array $data)
{
$model = new AccountModel();
$user = $model->where('username', $data['username'])
->first();
if(!$user)
return false;
return password_verify($data['password'], $user['password']);
}
}
?>
Thanks in advance guys!
First, the username and the email must be unique.
So, when the user enters an input either email or username
you can check if the user enters email using the following code
$email = $this->request->getPost('email');
if(substr_count($email , '#') > 0) // this is an email
check for the email if its exists in the database
else // not an email which means it is username
check for the username if its exists in the database
You can find this function substr_count()
Edit: You can use orWhere function so for example
$model->where('username' , $username)->orWhere('email',$email)->find()
so this will produce this statement
select * from tablename where username='' or email =''
In Codeigniter 4, there's a built in checker for email format validity and if email exists already in database without creating a database query. You just setup a Model and use the validations like
protected $validationRules = [
'username' => 'required|alpha_numeric_space|min_length[3]',
'email' => 'required|valid_email|is_unique[users.email]',
'password' => 'required|min_length[8]',
'pass_confirm' => 'required_with[password]|matches[password]'
];
more samples here, https://codeigniter.com/user_guide/models/model.html?highlight=valid_email

Controller returning login form while returning file with Symfony 5

I have a security problem using Symfony5.
I have configured security.yml:
access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
Everything works fine, except when I try to load a file (PDF), even if the route is allowed. The pdf shows the login form, but I'm already logged.
I feel it's because I return a File object in my controller:
public function viewpdf($id, \Knp\Snappy\Pdf $snappy) {
// some code
// load the file from the filesystem
$file = new File($path_file);
// display the file contents in the browser instead of downloading it
return $this->file($file, $file_name, ResponseHeaderBag::DISPOSITION_INLINE);
}
Same problem with another controller when I want to force download:
return new PdfResponse(
$snappy->getOutput($pageUrl),
$file_name
);
How can I view and download my pdf while I'm already logged in?
Thank you,
OK, I found the solution to this problem, for both cases:
// Inside controller
// KNP bbundle does not have the login/session data
$session = $this->get('session');
$session->save();
session_write_close();
$PHPSESSID =$this->get('session')->getId();
$output = $snappy->getOutput($pageUrl, array(
'cookie' => array(
'PHPSESSID' => $PHPSESSID
)));
if($download == 1) {
return new PdfResponse($output, $file_name);
} else {
return new Response(
$output, 200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => sprintf('filename="%s"', $file_name)
)
);
}

Migrating Cakephp2 Authentication to Cakephp 3

I'm moving an app from CakePHP 2 to CakePHP 3. There is a new hashing algorithm for Cake3. I'd like the existing users to be able to login to the app using their old passwords and for those passwords to then be updated to the new algorithm.
Unfortunatly, I can't get the correct hash to match up to what is in the database.
$person = $this->Auth->identify();
if(!$person){ # maybe they have old sha1 password?
$oldhash = Security::hash($this->request->data['password'],
'sha1', "oldsalt");
$person = $this->People->find()->where(['password' => $oldhash])->where(['email' =>$this->request->data['email'] ])->first();
if($person){
$person->password = Security::hash($this->request->data['password']);
$this->People->save($person);
}
}
The user is not found and if i debug the $oldhash out I get a different string than what is stored in the password field for that user.
What am I doing wrong?
Fallback classes
According to the documentation:
CakePHP provides a clean way to migrate your users’ passwords from one algorithm to another, this is achieved through the FallbackPasswordHasher class. Assuming you are migrating your app from CakePHP 2.x which uses sha1 password hashes, you can configure the AuthComponent as follows:
You will have to create an Custom Password Hasher class src/Auth/. A Custom Password hasher wil look something like this:
namespace App\Auth;
use Cake\Auth\AbstractPasswordHasher;
class LegacyPasswordHasher extends AbstractPasswordHasher {
public function hash($password)
{
return sha1($password);
}
public function check($password, $hashedPassword)
{
return sha1($password) === $hashedPassword;
} }
and then add it to passwordhasher in authenticate as fallback like this:
'authenticate' => [
'Form' => [
'passwordHasher' => [
'className' => 'Fallback',
'hashers' => [
'Default',
'Legacy'
]
]
]
]
The first name appearing in the hashers key indicates which of the classes is the preferred one, but it will fallback to the others in the list if the check was unsuccessful.
legacy is the Custom Password Hasher.
Updating the password
To update the users' password to the new hash you only have to add this code to your login procedure:
if ($this->Auth->authenticationProvider()->needsPasswordRehash()) {
$user = $this->Users->get($this->Auth->user('id'));
$user->password = $this->request->data('password');
$this->Users->save($user);
}
Documentation
More information about Changing hashing Algorithms
More information about the Custom Password Hasher
I had a CakePHP 2 app using Blowfish. Here's how I made it work with CakePHP 3:
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
// ...
'fields' => [
'username' => 'email',
'password' => 'pass', // make sure you match this with your corresponding login.ctp input name
],
// ...
'passwordHasher' => [
'className' => 'Fallback',
'hashers' => [
'Default' => ['hashType' => PASSWORD_BCRYPT],
]
],
// ...
]
],
Hope it helps someone googling this issue

How to manage CRSV token manually in Symfony?

I'm trying to use the CRSF token management without a FormType. So in a twig template i just use that to generate a token:
{{ csrf_token( inception_inscription ) }}
In the controller i'm trying this :
$tokenManager = $this->get('security.csrf.token_manager');
$token = $request->get('token');
inception = $this->container->getParameter('crsf_inscription_inception');
if (!$tokenManager->isTokenValid($tokenManager->getToken($inception, $token))) {
throw new HttpException(400, 'Invalid token');
}
But in fact the method isTokenValid always return true. I can force the $token vaiable to what i want, it's never false, so the validation is useless.
When i do debug step by step, i walk throught a Symfony\Component\Security\Csrf::getToken() and that method is testing that : ($this->storage->hasToken($tokenId)) whic always return false and force the process to generate a new Token.
I don't really undertand how it works.
Here is ore information about my code :
Symfony 2.6.x
framework:
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form:
csrf_protection:
enabled: true
field_name: token_my
csrf_protection:
enabled: true
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
handler_id: ~
name: 'my'
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
inception_inscription: %crsf_inscription_inception%
From what I understand, $tokenManager->getToken($tokenId) always generates a new, valid token. You would probably check the provided token instead, e.g.:
$tokenManager = $this->get('security.csrf.token_manager');
$tokenId = $this->container->getParameter('crsf_inscription_inception');
$tokenValue = $request->get('token');
$token = new CsrfToken($tokenId, $tokenValue);
if (!$tokenManager->isTokenValid($token)) {
throw new HttpException(400, 'Invalid token');
}

Symfony2 SonataAdminBundle Password field encryption

I have FOSUserBundle to manage my users, and SonataAdminBundle to manage my website... I have a problem, whenever I try to change/add a password to any user, the password isn't encoded into sha512, but it does when the user register itself inside fosuserbundle registration page...
So there isn't any problem with Symfony2 configuration neither fosuserbundle config, it may be inside SonataAdminBundle somewhere, or maybe into my admin class...
<?php
// src/Acme/DemoBundle/Admin/PostAdmin.php
namespace Web\DificilBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Web;
class UserAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('firstname')
->add('lastname')
->add('username')
->add('email')
->add('password', 'password') // -> I WANT THIS TO BE ENCODED INTO SHA512!
->add('roles','choice',array('choices'=>$this->getConfigurationPool()->getContainer()->getParameter('security.role_hierarchy.roles'),'multiple'=>true ));
//->add('body')
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('firstname')
->add('lastname')
->add('username')
->add('email')
->add('password')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('firstname')
->add('lastname')
->add('username')
->add('password')
->add('email')
->add('facebookid')
->add('roles');
//->add('password', 'password')
;
}
}
Found a solution for everyone who has the same problem as me, just on your admin class, where you define your Create/Update form, use this and your password will be perfectly encrypted and ready to log into your new user ;)
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
->add('plainPassword', 'repeated', array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle'),
'first_options' => array('label' => 'form.password'),
'second_options' => array('label' => 'form.password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
))
;
}

Resources