Yii 1.x email validator and localhost addresses - yii

Default, build-in Yii e-mail validator fails on e-mails like superuser#localhost -- treats them as not valid.
Is this intentional (reason?) or is it a bug in Yii?

I think for this case, you have to bulid your own pattern.
public function rules() {
return array(
array("email","patern","your regex for validation","message" => "Email is not correct")
)
}
http://www.yiiframework.com/doc/api/1.1/CEmailValidator#allowName-detail

Related

Laravel 8: how to translate two factor authentication default message

I'm usign Laravel Fortify and i want translate this default message how do it?
The provided two factor authentication code was invalid.
I found this message in this address but this is source and i can't change it
src/Http/Responses/FailedTwoFactorLoginResponse.php
public function toResponse($request)
{
$message = __('The provided two factor authentication code was invalid.');
if ($request->wantsJson()) {
throw ValidationException::withMessages([
'code' => [$message],
]);
}
return redirect()->route('login')->withErrors(['email' => $message]);
}
Did you install and develop Localization? Seems that message only need the locale. for apply the languages things

Laravel 8 Jetstream: unable to login with the account seeded using factories and seeder

I am working on a Laravel 8 project. I have noticed that a couple of things have changed including authentication. I am using Jetstream for authentication.
I have installed the Jetstream and I can register and login going to the route /register and /login on the browser. What I am doing now is that for local development, I am creating seeder class so that I can seed the users and log in using those seeded users for local development. But when I log in using those account, it is always complaining that "These credentials do not match our records.".
This is what I have done. I have registered an account on browser using password, "Testing1234". The password hash is saved in the users table. I copied the password and use it in the UserFactory class as follow.
<?php
namespace Database\Factories;
use App\Models\Role;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
use WithFaker;
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$tive4vPDzIq02SVERWxkYOAeXeaToAv57KQeF1kXXU7nogh60fYO2', //Testing.1234
'remember_token' => Str::random(10),
];
}
}
Then I created a user using factory as follow.
User::factory()->create(['email' => 'testing#gmail.com']);
Then I tried to log in using the user I just created. But it is always complaining, "These credentials do not match our records.". I cannot use the other passwords too. Even the default password that comes with the default user factory class. What is wrong with my code and how can I fix it?
Try using
User::factory()->make([
'email' => 'testing#gmail.com',
]);
I have finally found the issue.
In the JetstreamServiceProvider class, I have added the following code to customise the login flow.
Fortify::authenticateUsing(function (Request $request) {
});
My bad. That is what makes it failing.

Using CakePHP Form and Basic Authentication together

I've created a simple test site using CakePHP 3.8 and Authentication 1.0 to try it out. I'd like to use both Form and Basic authentication since the intended app will offer REST calls.
The site works properly if the HttpBasic is not included, that is the Login window is displayed. However, with HttpBasic, the site goes directly to basic authentication.
The code is directly from the cookbook.
What am I missing?
public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response)
{
$service = new AuthenticationService();
$service->setConfig([
'unauthenticatedRedirect' => '/users/login',
'queryParam' => 'redirect'
]);
$fields = [
'username' => 'user',
'password' => 'password',
];
// Load Identifiers
$service->loadIdentifier('Authentication.Password', compact('fields'));
// Load the authenticators
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Authentication.Form', [
'fields' => $fields,
'loginUrl' => '/users/login',
]);
$service->loadAuthenticator('Authentication.HttpBasic');
return $service;
}
As mentioned in the comments, using the form authenticator and the HTTP basic authenticator together won't work overly well, this is due to the fact that the authentication service won't stop executing all loaded authenticators, unless one of them returns a response that indicates successful authentication.
This means that you'd always be presented with the authentication challenge response, and never see your login form. Only the actual authentication part would work in that constellation, ie directly sending your login credentials as form data to the login endpoint.
If you don't actually need the basic auth challenge response that is preventing you from accessing the login form, then you could use a custom/extended authenticator that doesn't cause a challenge response to be returned, which should be as simple as overriding \Authentication\Authenticator\HttpBasicAuthenticator::unauthorizedChallenge():
src/Authenticator/ChallengelessHttpBasicAuthenticator.php
namespace App\Authenticator;
use Authentication\Authenticator\HttpBasicAuthenticator;
use Psr\Http\Message\ServerRequestInterface;
class ChallengelessHttpBasicAuthenticator extends HttpBasicAuthenticator
{
public function unauthorizedChallenge(ServerRequestInterface $request)
{
// noop
}
}
$service->loadAuthenticator(\App\Authenticator\ChallengelessHttpBasicAuthenticator::class);
Also not that you might need to add additional checks in case your application uses the authentication component's setIdentity() method, which would cause the identity to be persisted in the session, even when using stateless authenticators. If you don't want that, then you'd need to test whether the successful authenticator is stateless before setting the identity:
$provider = $this->Authentication->getAuthenticationService()->getAuthenticationProvider();
if (!($provider instanceof \Authentication\Authenticator\StatelessInterface))
{
$this->Authentication->setIdentity(/* ... */);
}

Laravel 5.1 Middleware to check the creation date from a user to change password

I'm developing a webapp with Laravel 5.1 and I'm building the authentication system and I have to check if the user has not changed his password in six months or more and I would use a middleware to check this but I didn't find how I can do it properly. I created a global middleware but it is not working because I can't get the authenticated user.
It is possible that I have to use an AfterMiddleware to check the password?
First explain/state when you want the user to force to change the password?
While authenticating or after success authentication?
then i can give you a solution
then You need to overwrite the method postLogin in AuthController
public function postLogin(Request $request){
$credentials = ['email' => $request->email, 'password' => $request->password];
if (Auth::attempt($credentials, $request->has('remember'))) {
if((strtotime(Auth::user()->created_at) < strtotime('6 month ago'))){
return redirect('your-reset-path);//redirect to password reset page
}else{
return redirect()->intended('/');
}
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
this will do the job if you want to check on created_at but you rather use another field with time-stamp(last_password_updated) that will only updated when password is changed and when it is first created,it will be more efficient.

Authenticate Symfony2 REST API with Google Account

I'm working with Symfony2 and FOSOauthServerBundle in a REST API. I would wish that some user could log in by a client app using their Google Account, for instance.
From my REST server, by web, I can log in with my Google Account (using HWIOauthBundle), but I need to send to the client app an access_token (like FOSOauthServerBundle does).
I'm interested on persist the access_token that Google send to me in my data base and at the same time, send to the client app the json message {'access_token': 'XMekfmns.... } with Google's (and now my REST API too) access_token.
I don't know if my approach is right. Any ideas?
(sorry for my english ;-) )
Thank you very much
This is my (dirty) solution, but I hope people understand what I want to.
From the client side, the user send the request to get authorization from the google account (I'm using Symfony2 with HWIOauthBundle)
http://myserver.com/connect/google
This present the Google login form. The user fill the form and submit it. If success exists, there will be a redirect to myserver.com where the user will logged.
I catch the event onAuthenticationSuccess ...
<?php
namespace App\Bundle\Handler;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\HttpFoundation\Request,
Symfony\Component\HttpFoundation\RedirectResponse,
Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Router;
class SecurityHandler implements AuthenticationSuccessHandlerInterface
{
private $router;
public function __construct(Router $router)
{
$this->router = $router;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$user = $token->getUser();
return new RedirectResponse($this->router->generate('api_get_token', array(
'clientRandomId' => '5ewv02jcis08wsgggk4wow4so0gokco0g4s8kkoc4so4s0gw4c'
)));
}
#clientRandomId value is an existing value in the table (entity) Client ...
#... in the database.
}
... to redirect to a Controller where it will generate an access_token and refresh_token, where they will be saved in the database. At the end, it will be sent a json response to the user, like FOSOauthServerBundle does.
<?php
namespace App\Bundle\Controller\Api;
use Symfony\Bundle\FrameworkBundle\Controller\Controller,
Symfony\Component\HttpFoundation\JsonResponse,
Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\RestBundle\Controller\FOSRestController,
FOS\RestBundle\Controller\Annotations\Route,
FOS\RestBundle\Controller\Annotations\NamePrefix,
FOS\RestBundle\Controller\Annotations\Prefix;
use FOS\RestBundle\Routing\ClassResourceInterface;
use App\Bundle\Entity\AccessToken;
use App\Bundle\Entity\RefreshToken;
class TokenController extends FOSRestController implements ClassResourceInterface {
#this method has the route named 'api_get_token'
public function getAction($clientRandomId)
{
$user = $this->get('security.context')->getToken()->getUser();
#control if user exist ...
#We force the loggout
$this->container->get('security.context')->setToken(null);
$em = $this->get('doctrine')->getManager();
$client = $em->getRepository('AppBundle:Client')->findOneBy(array('randomId' => $clientRandomId));
#control if client exist ...
$expiresAt = time() + 3600;
$accessToken = new AccessToken;
$accessToken->setClient($client);
$accessToken->setToken('access_token'); #This is only an example
$accessToken->setExpiresAt($expiresAt);
$accessToken->setUser($user);
$refreshToken = new RefreshToken;
$refreshToken->setClient($client);
$refreshToken->setToken('refresh_token'); #This is only an example
$refreshToken->setExpiresAt($expiresAt);
$refreshToken->setUser($user);
$em->persist($accessToken);
$em->persist($refreshToken);
$em->flush();
$jsonData = array(
'access_token' => $accessToken->getToken(),
'expires_in' => 3600,
'token_type' => 'bearer',
'scope' => null,
'refresh_token' => $refreshToken->getToken()
);
$response = new JsonResponse($jsonData);
return $response;
}}
I know this is not the best solution but maybe it guide you to a better solution.