How use middleware for differentiate between normal user and admin - laravel-5.5

I have created a middleware the purpose of this middleware is that to differentiate between admin and normal user but it is not working properly whatever user or admin come it redirect to the same page and my condition is not working and I am using the same table for normal user and admin. I am using laravel 5.5 for this.
if (Auth::user() && Auth::user()->isAdmin == 1) {
return $next($request);
}
return redirect()->action('HomeController#index');

okay follow my guide
run this comment in your terminal "make sure cd to ur project"
php artisan make:middleware IsAdmin
Edit isAdmin file
public function handle($request, Closure $next)
{
if (Auth::user() && Auth::user()->admin == 1) {
return $next($request);
}
return redirect('/');
}
Add it to the routeMiddleware array in your kernel file by opening app/Http/Kernel.php
'admin' => \App\Http\Middleware\IsAdmin::class,
Apply the middleware to your route
Route::get('admin_area', ['middleware' => 'admin', function () {
//
}]);
Hop this is work for you

Open Middleware -> RedirectIfAuthenticated.php
1.Remove this code:
public function handle($request, Closure $next, $guard = null) {
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
2.copy/paste this one
public function handle($request, Closure $next, $guard = null) {
if (Auth::guard($guard)->check()) {
return redirect('/home');
}else{
return redirect()->action('AdminController#login')->with('flash_message_error','Please login to access');
}
return $next($request);
}
}

Related

AWS Amplify, how to check if user is logged in?

I've been using the aws-amplify library with ionic and was wondering how I would check if a user is logged in? I'm coming from a firebase background so this is quite different. This is so that I can grant access to certain pages based on the user's log in status. In my auth provider I import Amplify {Auth}. I can see that it's possible to get several pieces of data but I'm not sure what to use. There's currentUserPoolUser, getCurrentUser(), getSyncedUser(), currentAuthenticatedUser, currentSession, getCurrentUser(), userSession, currentUserCredentials, currentCredentials and currentUserInfo. I can't seem to find any documentation on any of this either. Everything I've read and watched covers up until the user signs in... Is this all supposed to be done on the client? Thanks.
I'm using the ionViewCanEnter() function in every page to allow/deny access. The return value of this function determines if the page can be loaded or not (and it is executed before running the costructor). Inside this function you have to implement you logic.
In my case, using Amplify, I'm doing this:
async function ionViewCanEnter() {
try {
await Auth.currentAuthenticatedUser();
return true;
} catch {
return false;
}
}
Since amplify currentAuthenticatedUser() return a promise I use async await to wait for the response to know if the user is logged in or not.
Hey I think for now you can only use Auth.currentUserInfo(); to detect whether logged in or not. It will return undefined if you are not logged in or an object if you are.
This can be achieved using the fetchAuthSession() method of Auth.
final CognitoAuthSession res = await Amplify.Auth.fetchAuthSession();
if (res.isSignedIn) {
// do your thang
}
if you are using angular with ionic then you can do somthing like this in your authenticator service
import {AmplifyService} from 'aws-amplify-angular';
...
constructor(private amplifyService:AmplifyService)
{
this.amplifyService.authStateChange$.subscribe(auth => {
switch (auth.state) {
case 'signedIn':
this.signedIn = true;
case 'signedOut':
this.signedIn = false;
break;
default:
this.signedIn = false;
}
}
}
then you can use this.signedIn in your router with canActivate guard.
Angular router guard: https://angular.io/guide/router#preventing-unauthorized-access
You can make it a custom hook by listening to the hub (ionViewCanEnter from the above answers is for bootup of the app):
Hook tsx:
import {useState, useEffect} from 'react';
import {Hub, Auth} from 'aws-amplify';
export default function AuthenticatedStatus(): Boolean {
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
async function ionViewCanEnter() {
console.log('hey');
try {
const authenticatedUser = await Auth.currentAuthenticatedUser();
if (authenticatedUser !== undefined) {
setIsAuthenticated(true);
} else {
setIsAuthenticated(false);
}
} catch {
setIsAuthenticated(false);
}
}
useEffect(() => {
ionViewCanEnter();
});
useEffect(() => {
const listener = data => {
switch (data.payload.event) {
case 'signIn' || 'autoSignIn' || 'tokenRefresh':
console.log('is authenticated');
setIsAuthenticated(true);
break;
case 'signOut' || 'signIn_failure' || 'tokenRefresh_failure' || 'autoSignIn_failure':
console.log('is not authenticated');
setIsAuthenticated(false);
break;
}
};
Hub.listen('auth', listener);
});
return isAuthenticated;
}
how to use:
const isAuthenticated = AuthenticatedStatus();
An example that's worked with me, careful for flow control, both
event-loop style and async/await style:
import { Auth } from "aws-amplify";
...
exampleIsLoggedIn() {
const notLoggedInStringThrown = "The user is not authenticated";
Auth.currentAuthenticatedUser().then(
// eslint-disable-next-line #typescript-eslint/no-unused-vars
(_currentAuthenticatedUser) => {
this.$log.debug("Yes, user is logged in.");
},
(error) => {
if (error === notLoggedInStringThrown) {
this.$log.debug("No, user is not yet logged in.");
} else {
this.$log.error(error);
}
}
);
},
async exampleIsLoggedInAsync() {
const notLoggedInStringThrown = "The user is not authenticated";
try {
/* currentAuthenticatedUser = */ await Auth.currentAuthenticatedUser();
this.$log.debug("Yes, user is logged in.");
} catch (error) {
if (error === notLoggedInStringThrown) {
this.$log.debug("No, user is not yet logged in.");
} else {
this.$log.error(error);
}
}
},
import { Auth } from 'aws-amplify';
Auth.currentAuthenticatedUser({
// Optional, By default is false. If set to true,
// this call will send a request to Cognito to get the latest user data
bypassCache: false
})
.then((user) => console.log(user))
.catch((err) => console.log(err));
This method can be used to check if a user is logged in when the page is loaded. It will throw an error if there is no user logged in. This method should be called after the Auth module is configured or the user is logged in. To ensure that you can listen on the auth events configured or signIn.
Source: https://docs.amplify.aws/lib/auth/manageusers/q/platform/js/#retrieve-current-authenticated-user

can i change user model credentials in loopback?

I am building an API for login and registration using loopback framework.
Loopback provides, by default, model User for login, register and other similar stuff. Default way to provide user's credentials in LoopBack is username-password/email-password but I want to use mobileNo-password/email-password as user's login credentials. So how can I do that? How can I change default credential option in User model?
You can achieve that in two ways:
If not using username field in User model, you can use it to store mobile number, mobileNo.
You have to edit user.js to accept mobileNo field as login credentials. User.login and User.normalizeCredentials are used for login process, so you can edit them like provided in the code snippet.
Note: Don't forget to add mobileNo to user.json
User.normalizeCredentials method
`User.normalizeCredentials = function(credentials, realmRequired, realmDelimiter) {
var query = {};
credentials = credentials || {};
if (!realmRequired) {
if (credentials.email) {
query.email = credentials.email;
} else if (credentials.mobileNo) {
query.mobileNo = credentials.mobileNo;
}
} else {
if (credentials.realm) {
query.realm = credentials.realm;
}
var parts;
if (credentials.email) {
parts = splitPrincipal(credentials.email, realmDelimiter);
query.email = parts[1];
if (parts[0]) {
query.realm = parts[0];
}
} else if (credentials.mobileNo) { //added mobileNo.
parts = splitPrincipal(credentials.mobileNo, realmDelimiter);
query.mobileNo = parts[1];
if (parts[0]) {
query.realm = parts[0];
}
}
}
return query;
};`
User.login method
`User.login = function(credentials, include, fn) {
.
.
.
.
.
if (!query.email && !query.mobileNo) {
var err2 = new Error('Mobile number or email is required');
err2.statusCode = 400;
err2.code = 'MOBILE_NUMBER_EMAIL_REQUIRED';
fn(err2);
return fn.promise;
}
}`

Grails 2.4.4 generated controller test fails

I have test for the save action of a controller. It just executes the action with correct params, but the problem is on the redirectedUrl line: it is null.
Using the app, after saving the domain instance, I get the redirection to the show action and the show view is rendered correctly.
Any clues of what's the problem here?
The controller:
#Transactional(readOnly = true)
class FolderController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
...
#Transactional
def save(Folder folderInstance) {
if (folderInstance == null) {
notFound()
return
}
if (folderInstance.ehrId)
{
def ehr = ehr.Ehr.get(folderInstance.ehrId)
ehr.directory = folderInstance
ehr.save()
}
if (folderInstance.hasErrors()) {
respond folderInstance.errors, view:'create'
return
}
folderInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'folder.label', default: 'Folder'), folderInstance.id])
redirect folderInstance
}
'*' { respond folderInstance, [status: CREATED] }
}
}
...
}
The test:
#TestFor(FolderController)
#Mock(Folder)
class FolderControllerSpec extends Specification {
...
void "Test the save action correctly persists an instance"() {
when:"The save action is executed with a valid instance"
response.reset()
populateValidParams(params)
def folder = new Folder(params)
controller.save(folder)
println folder.errors // no errors
then:"A redirect is issued to the show action"
response.redirectedUrl == '/folder/show/1'
controller.flash.message != null
Folder.count() == 1
}
...
}
The output:
junit.framework.AssertionFailedError: Condition not satisfied:
response.redirectedUrl == '/folder/show/1'
| | |
| null false
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse#112b2f1
at directory.FolderControllerSpec.Test the save action correctly persists an instance(FolderControllerSpec.groovy:61)
Grails scaffold controllers are smarter controllers. They respect the request format and generate the response accordingly.
For example your save action -- it redirects to the show action if the request format is form otherwise it returns saved domain instance with status CREATED.
Following code is responsible for this
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'folder.label', default: 'Folder'), folderInstance.id])
redirect folderInstance
}
'*' { respond folderInstance, [status: CREATED] }
}
And in you test cases, your request is not of form type and hence redirectedUrl is null.
To make form request, add following code in you test case before making save call--
request.format = 'form'
Hope this helps.
I forgot to add the allowedMethods field.
The first problem was that the generated tests doesn't sets the right request method for the correspondent actions, so to call .save() this is needed: controller.request.method = "POST"
Then what #user1690588 suggested (request.format = 'form') did the trick to get the right redirectedUrl.
My final test looks like this:
void "Test the save action correctly persists an instance"() {
when:"The save action is executed with a valid instance"
response.reset()
populateValidParams(params)
def folder = new Folder(params)
controller.request.method = "POST"
request.format = 'form'
controller.save(folder)
then:"A redirect is issued to the show action"
response.redirectedUrl == '/folder/show/1'
controller.flash.message != null
Folder.count() == 1
}

Unit test filter with a mocked service

I'm using Grails 2.3.8 and trying to create a unit test for a filter that uses a service.
The filter:
class LicenseFilters {
def licenseService
def filters = {
all(controller:'*', action:'*') {
before = {
if(!licenseService.checkLicense()){
redirect(controller:"licenseExpired")
return false
}
}
}
}
}
The spec, first attempt:
#TestFor(ExecutionTraceController)
#Mock(LicenseFilters)
class LicenseFiltersSpec extends Specification{
void "Test filter redirects when license is wrong"() {
given:
LicenseFilters bean=applicationContext.getBean("com.nortia.sgmentia.license.LicenseFilters")
bean.licenseService=this.buildLicenseServiceStub(false)
when:
withFilters(action:"list") {
controller.list()
}
then:
response.redirectedUrl == '/licenseExpired'
}
private LicenseService buildLicenseServiceStub(boolean ok){
LicenseService result=Stub(LicenseService)
result.checkLicense() >> ok
return result
}
}
But it turns out (by debugging) that the bean that I grab from the context it is NOT the same one that receives the request thus I still get a NPE.
In a second attempt I try using defineBeans:
void "Test filter redirects when license is wrong"() {
given:
defineBeans {
licenseService(MethodInvokingFactoryBean){
targetObject = this
targetMethod= "buildLicenseServiceStub"
arguments=[false]
}
}
when:
withFilters(action:"list") {
controller.list()
}
then:
response.redirectedUrl == '/licenseExpired'
}
But the mocked bean is neither bean instanciated nor inyected.
Should I try to inyect the service manually into the filter??
There was this issue https://jira.grails.org/browse/GRAILS-8976 but it is closed.
I came across a similar situation and was able to fix it by adding the service to the #Mock annotation, i.e. #Mock([LicenseFilters, LicenseService]).
In your case the spec would look something like the following:
#TestFor(ExecutionTraceController)
#Mock([LicenseFilters, LicenseService])
class LicenseFiltersSpec extends Specification {
void "Test filter redirects when license is wrong"() {
given:
defineBeans {
licenseService(MethodInvokingFactoryBean) {
targetObject = this
targetMethod = "buildLicenseServiceStub"
arguments = [false]
}
}
when:
withFilters(action: "list") {
controller.list()
}
then:
response.redirectedUrl == '/licenseExpired'
}
private LicenseService buildLicenseServiceStub(boolean ok) {
LicenseService result = Stub(LicenseService)
result.checkLicense() >> ok
return result
}
}
Note: that mocking the service in this manner will, by default, inject an instance of the actual LicenseService into your filter. So, if the above defineBeans block is removed the actual implementation of LicenseService.checkLicense() will be called.
I finally found a workaround to make it work going with the second approach (using defineBeans).
The service is not being autowired into the filter so I finally did it manually with a pseudo-singleton:
class LicenseFilters {
def licenseService
def filters = {
all(controller:'*', action:'*') {
before = {
if(!this.licenseService){
this.licenseService=applicationContext.getBean("licenseService")
}
if(!this.licenseService.checkLicense()){
redirect(controller:"licenseExpired")
return false
}
}
}
}
}
Quite ugly but a solution at least.
Hope it helps someone out there.

How can I add a related entity to a user object at the point of creation in FOSUserBundle?

In Symfony2 RC3, I am trying to create a related entity on a User object (FOSUserBundle) at the point of user creation so that I can display the appropriate fields on an edit profile form. I am doing the following in the RegistrationFormHandler.
class RegistrationFormHandler
{
protected $request;
protected $userManager;
protected $form;
public function __construct(Form $form, Request $request, UserManagerInterface $userManager)
{
$this->form = $form;
$this->request = $request;
$this->userManager = $userManager;
}
public function process($confirmation = null)
{
$user = $this->userManager->createUser();
$this->form->setData($user);
if ('POST' == $this->request->getMethod()) {
$this->form->bindRequest($this->request);
if ($this->form->isValid()) {
if (true === $confirmation) {
$user->setEnabled(false);
} else if (false === $confirmation) {
$user->setConfirmationToken(null);
$user->setEnabled(true);
}
$prog = new \MyBundle\CoreBundle\Entity\Programme();
$prog->setStartDate(date_create());
$prog->setEndDate(date_create());
$prog->setWeeklyTarget(4);
$prog->setGoal('');
$user->addProgrammes($prog);
$this->userManager->updateUser($user);
return true;
}
}
return false;
}
}
The programme record does get created in the database but with a null user_id so it seems the association isn't working correctly. Anyone know what might be causing this?
The solution was to do $programmes->setUser($this); in the addProgrammes method of my User entity