How to protect admin area from users by role in laravel 5.6? - laravel-5.5

I was looking for simple Laravel 5.6+ version roles and users solution.
I want to have one users table. So I added user_type in my table as string in
$table->enum('role', ['admin', 'user']);
Which files should I create or update to protect everything under /admin route. And do not let to use admins routes for users?

You should create a middleware that is active in all /admin routes. In this middleware you should check if the user that is logged in (Auth::user()) has the "admin"-role.
Auth::user() references the User-model.
So in the User-model you can create a function like isAdmin():
public function isAdmin()
{
return $this->role === 'admin'
}
In the Middleware (or wherever you want it) you can just write
if(Auth::user()->isAdmin()) {
// do something if user is admin
} else {
// do something if user is not admin
}
Since it is in the User-model you can also write $user->isAdmin() for regular user models.

Related

Flutter AWS Auth: How to get custom user attribute?

How do I get in Flutter, the cognito custom user attribute for user?
await Amplify.Auth.fetchUserAttributes();
returns only user attributes but not the custom defined ones.
(I have added the attribute to the schema and I am sure it's there, in the AWS UI it's there.)
The fetchUserAttributes function returns a list of AuthUserAttributes including the custom ones you've defined. When you have that list you can iterate through it, and get the attributes you want.
const res = await Amplify.Auth.fetchUserAttributes();
for (var attr in res) {
if (attr.userAttributeKey == CognitoUserAttributeKey.custom('customAttr') {
customAttr = attr.value;
}
}
If the custom attribute isn't there, make sure the user have that attribute.
The issue was that these custom attributes, after they are created, they are not by default readable or writable.
For further explanations, check https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-attribute-permissions-and-scopes
Go to cognito - app clients - details - and very bottom to change permissions

Store UserTokens generated by ASP.Net Core identity for external login provider

I am using Facebook as external login of ASP.Net Core identity.
I would like, even if the user logged in with Facebook, the user to fill his profile on the website.
For that I use the ExternalLoginCallback method, from which I would like to get data from Facebook such as date of birth, location (country), ...
One issue is if the user unchecked some of the permissions, the default call to Facebook fails:
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
return RedirectToAction(nameof(Login));
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
I would also need to do some additional checks on user data, which would require calling directly the Graph API.
My blocking points:
- In the ExternalLoginCallback method, I would need to separate the 'country' and 'birthday' to avoid the Facebook API to return an error in case of the user didn't grant the permission
- For that I would need the the user access_token (and for additional calls in the method), I don't see how to get it even if it is used by the Facebook Identity framework
- Once the profile created, I would like to get access to this access_token, which should be stored in the UserTokens table (I guess?), but I can't find it there, the table is empty. (my DbContext is a class extending IdentityDbContext<AppUser, AppRole, long>, don't know if it has an impact)
I have found this answer https://stackoverflow.com/a/42670559/4881677 which may help, but not sufficient.
Any help? :)
In order to store the user Facebook token, it requires to specify it in the options (not stored by default).
var fo = new FacebookOptions();
fo.SaveTokens = true;
From there we can call the graph method permissions to get the available permissions: https://graph.facebook.com/me/permissions?access_token={token}
Then it can be read with something like this:
foreach (var perm in data)
{
perms.Add((string)perm["permission"], (string)perm["status"]);
}

Sitecore Virtual User Login Experience Profile

I need to validate user credentials from external service, therefore I'm using the VirtualUser authentication.
BuildVirtualUser, checking for the roles to set to him, saving the user Profile and then login with that name.
I'm facing a problem, that everyday that i login, with the same credentials Sitecore creates a new user in Experience Profile.
What i need to change in my code to assure that, with virtual user login, Sitecore gets the old experience profile of the user?
I was thinking in creating the user in sitecore with same generic password. Instead of using the virtual user, and authenticate directly with sitecore. Is that correct?
Here's my code:
Sitecore.Security.Accounts.User user = Sitecore.Security.Authentication.AuthenticationManager.BuildVirtualUser(sitecoreUser, true);
string roleName = #"newRole\User";
Sitecore.Security.Accounts.Role demoRole = Sitecore.Security.Accounts.Role.FromName(roleName);
if (Sitecore.Security.Accounts.Role.Exists(roleName) && !demoRole.IsMember(user, true, false))
{
user.Roles.Add(Sitecore.Security.Accounts.Role.FromName(roleName));
}
user.Profile.Name = name;
user.Profile.Email = email;
user.Profile.FullName = fullname;
user.Profile.Save();
Sitecore.Security.Authentication.AuthenticationManager.Login(user.Name);
Tracker.Initialize();
Code looks fine, but you miss one important thing: to identify your user/contact.
You need to add next line of code:
Tracker.Current.Session.Identify(email);
Please check next link to find more information about how to identify contacts:
https://doc.sitecore.net/sitecore_experience_platform/setting_up__maintaining/xdb/contacts/identifying_contacts

Using SitecoreUser.Profile with Forms Authentication

We use sitecore to manage our registered users (extranet domain) and when creating new virtual users we give it an email using the Profile.Email property and then call the Profile.Save() method.
Another property somewhere else reads the userProfile.Email, everything is fine at the beginning.
Plus we use Forms authentication with the remember me feature.
The problem is when we close the browser and reopen it Sitecore.Context.User contains info about the actual user who clicked remember me but the User.Profile always has the Email null.
I tried Reload() and initialize() they don't work. I also tried getting the user again via the username (User.FromName()) but the returned user object also doesn't have the Profile Email.
What is being done wrong?
There is one very important remark in Security API Cookbook. It is related to Sitecore 6 but as far as I know it should work with Sitecore 8 as there was no important changes in Security model. It worked for Sitecore 7.
Important You must log in a virtual user only after you assign Roles and Profile properties to them. The Roles and Profile properties that are assigned after logging in are lost upon subsequent request.
Sitecore.Security.Accounts.User user =
Sitecore.Security.Authentication.AuthenticationManager.BuildVirtualUser(#"domain\user"
, true);
if (user != null)
{
string domainRole = #"domain\role";
if (Sitecore.Security.Accounts.Role.Exists(domainRole))
{
user.Roles.Add(Role.FromName(domainRole));
}
user.Profile.Email = "user#domain.com";
user.Profile[“Custom Property”] = “Custom Value”;
user.Profile.Save();
Sitecore.Security.Authentication.AuthenticationManager.LoginVirtualUser(user);
}

Why Sitecore create virtual users with all extranet roles?

I am not sure about BuildVirtualUser method behavior in Sitecore 6.6 update 3
I have the following code:
bool isAuthenticated = true;
string userName = string.Format("{0}\\{1}", "extranet", user.Login);
SC.Security.Accounts.User virtualUser = SC.Security.Authentication.AuthenticationManager.BuildVirtualUser(userName, isAuthenticated);
but after BuildVirtualUser method call virtualUser variable contain all extranet roles.
I expect that just my following code should attach role to user.
foreach(var role in user.Permissions)
{
string domainRole = string.Format("{0}\\{1}", "extranet", "USER_EDIT");
if (SC.Security.Accounts.Role.Exists(domainRole))
{
virtualUser.RuntimeSettings.AddedRoles.Add(domainRole);
}
}
Why does it happening? What do I need to do to fix it?
Update 1
I have discovered that first time BuildVirtualUser creates user with 0 roles,
roles can be succesfully added, but after logout and login procedure with the same user name, roles that were added during first time automaticaly attaching to new user. In my opinion this bahavior is not good, in case someone can edit user roles in external system.
Try this:
user.Roles.Add(Sitecore.Security.Accounts.Role.FromName(domainRole));
from:
http://sdn.sitecore.net/upload/sitecore6/sc61keywords/security_api_cookbook_usletter.pdf
I am not sure what your for each loop is, but it's kind of redundant your not doing anything with each 'role'.
SC.Security.Accounts.User virtualUser = SC.Security.Authentication.AuthenticationManager.BuildVirtualUser(userName, true);
virtualUser.RuntimeSettings.AddedRoles.Clear();
virtualUser.Roles.RemoveAll();
this code is help to update user roles dynamicly.
But I still not undetstend why sitecore cache roles for virtual users.