I'am building my project using Laravel 4.1 with Sentry 2 as authorization and authentication package.
I've managed to log users in, register them and assign proper user groups.
I have 3 user groups:
Administrator
Presenter
Registered
I want to achieve 2 things:
Administrators and Presenters can have access to the Administration Panel. Users don't.
Restrict views in Administration Panel for Presenters. I want them to see only few views (links), for example only Schedule.
I've never used roles before and this is first time i use Sentry 2. That's why i'd like to ask for some help. Some point, how to start. How can i achieve both?
For more general permission checks I would look at inGroup() helper:
// Find the user using the user id
$user = Sentry::findUserByID(1);
// Find the Administrator group
$admin = Sentry::findGroupByName('Administrator');
// Check if the user is in the administrator group
if ($user->inGroup($admin)) {
// User is in Administrator group
} else {
// User is not in Administrator group
}
Define permission for all groups.
check this tutorial https://cartalyst.com/manual/sentry/users/helpers
and focus on hasAccess($permission) and hasAnyAccess($permissions)
in filter.php
/**
* hasAcces filter (permissions)
*
* Check if the user has permission (group/user)
*/
Route::filter('hasAccess', function($route, $request, $value)
{
try {
$user = Sentry::getUser();
if( ! $user->hasAccess($value)) {
if(Sentry::check())
return Redirect::to('portal')->with('message', 'No Access.');
else
return Redirect::to('registration#login')->with('message', 'No Access.');
}
} catch (Cartalyst\Sentry\Users\UserNotFoundException $e) {
if(Sentry::check())
return Redirect::to('portal')->with('message', 'User not found.');
else
return Redirect::to('registration#login')->with('message', 'User not found.');
}
});
/**
* InGroup filter
*
* Check if the user belongs to a group
*/
Route::filter('inGroup', function($route, $request, $value) {
try {
$user = Sentry::getUser();
$group = Sentry::findGroupByName($value);
if( ! $user->inGroup($group)) {
if(Sentry::check())
return Redirect::to('portal')->with('message', 'No Access.');
else
return Redirect::to('registration#login')->with('message', 'No Access.');
}
} catch (Cartalyst\Sentry\Users\UserNotFoundException $e) {
if(Sentry::check())
return Redirect::to('portal')->with('message', 'User not found.');
else
return Redirect::to('registration#login')->with('message', 'User not found.');
} catch (Cartalyst\Sentry\Groups\GroupNotFoundException $e) {
if(Sentry::check())
return Redirect::to('portal')->with('message', 'Group not found.');
else
return Redirect::to('registration#login')->with('message', 'Group not found.');
}
});
Routes ->
Route::group(array( 'before' => 'Sentry|inGroup:Administrators'), function() {
Route::get('manageusers', array('as' => 'manageusers', 'uses' => 'UserController#viewUsersList'));
});
Related
I have google OATH setup via socialite (only for within our organisation) and everything is working fine.
One thing I'd like to try and do is catch this "error" and get redirected back to our login page with a custom message telling the user that they do not belong to our organisation.
In principle this works fine, they can just hit the back button... but for fluidity and design, I'd like to catch this and redirect back to our home page.
Is this even possible? If so, how would you recommend I go about it?
public function show()
{
return view('auth.login');
}
public function redirectToProvider($driver)
{
if( ! $this->isProviderAllowed($driver) ) {
return $this->sendFailedResponse("{$driver} is not currently supported");
}
try {
return Socialite::driver($driver)->redirect();
} catch (Exception $e) {
return $this->sendFailedResponse($e->getMessage());
}
}
public function handleProviderCallback( $driver )
{
try {
$user = Socialite::driver($driver)->user();
} catch (Exception $e) {
return $this->sendFailedResponse($e->getMessage());
}
// check for email in returned user
return empty( $user->email )
? redirect()->intended('/login?failed=1')
: $this->loginOrCreateAccount($user, $driver);
}
protected function sendSuccessResponse()
{
return redirect()->intended('/');
}
protected function sendFailedResponse($msg = null)
{
return redirect()->intended('/login?failedResponse='.$msg);
}
protected function loginOrCreateAccount($providerUser, $driver)
{
// check for already has account
$user = User::where('email', $providerUser->getEmail())->first();
// if user
if( $user ) {
// update the avatar and provider that might have changed
$user->update([
'avatar' => $providerUser->avatar,
'provider' => $driver,
'provider_id' => $providerUser->id,
'access_token' => $providerUser->token
]);
} else {
return redirect()->intended('/login?noUser=1');
}
// login the user
Auth::login($user, true);
return $this->sendSuccessResponse();
}
private function isProviderAllowed($driver)
{
return in_array($driver, $this->providers) && config()->has("services.{$driver}");
}
i have this function for get orders for only authenticated user:
function show($uid) {
try {
$user = User::findOrFail($uid);
$orders = $user->orders;
return $orders;
}catch (\Exception $e) {
return response()->json(['messsage' => "cannot show order for this user"]);
}
}
it is a end point for API in this route:
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::get('/order/{id}', [OrdersController::class, 'show']);
});
but now if anyone just add any uid, he can display all orders...
my question is how can i protect this function so just auth user can fetch data: and i have used Sanctum in my project
in laravel with blade i just do like this:
function show() {
$uid = auth()->id();
try {
$user = User::findOrFail($uid);
$orders = $user->orders;
return $orders;
}catch (\Exception $e) {
return response()->json(['messsage' => "cannot show order for this user"]);
}
}
Thank you all...... I have found the solution, i could find the id of Authenticated user simply by this since i use the guard (sanctum):
auth('sanctum')->user()->id
this will give me the id for auth user depending on the token.
and the solution will be like this:
function show(Request $request) {
try {
$uid = auth('sanctum')->user()->id;
$user = User::findOrFail($uid);
$orders = $user->orders;
return $orders;
}catch (\Exception $e) {
return response()->json(['messsage' => "cannot show order for this user"]);
}
}
I have route:
Route::get('#{username}', 'HomePageController#username')->name('user.profile');
that route to allow for everyone to see the profile ( contains his info and his cv .. etc ), and in the beginning of register any user user must wait to active his account by the admin
I need to see if account of user still under process show above route just for him. and when the account is active open above route for everyone can see his profile.
I tried to create middleware but don't know how can I forbid the guest user
My wrong shut:
public function username($username)
{
$user = User::where('username' , '=' , $username)->firstOrFail();
if($user->active){
return view('frontend.user_profile',compact('user','projects_last','first_project','whole_projects'));
}else{
return redirect('/');
}
}
What the best scenario to do something like that?
thanks.
if ($user->active) {
// Everyone can see
} else {
if (Auth::user() && Auth::user()->username == $username) {
// only auth and himself can see
} else {
// redirect to home page
}
}
if($user->active || $username == Auth::user()->username){
return view('frontend.user_profile',compact('user','projects_last','first_project','whole_projects'));
}else{
return redirect('/');
}
You can try this
public function username($username)
{
$user = User::where(['username' => $username,'status' => 'active'])->firstOrFail();
if($user && auth()->user()->username == $username){
return view('frontend.user_profile',compact('user','projects_last','first_project','whole_projects'));
}else{
return abort(403, 'Unauthorized action.');
}
}
}
You can also use it like this
if( $username == Auth::user()->username){
return view('frontend.user_profile',compact('user','projects_last','firs. t_project','whole_projects'));
}else{
return abort(403, 'Unauthorized action.');
}
I create postSignIn Method and want to verified :
email, password, verifiedFlag
First there was no problem for create postSignIn Method, like :
public function postSignIn(){
if(Auth::attempt(array('email' => Input::get('email'),'password' => Input::get('password'),'verifiedFlag'=>1))){
return Redirect::route('home-view');
}
else{
return "Email/Password wrong or Your Account not verified by Admin";
}
}
But now I try to make it more user friendly by Separate Alert for
Account not Verified, and
Email/Password Wrong
and now I try to make it like this:
if(Auth::attempt(array('nim' => Input::get('nim'),'password' => Input::get('password')))){
Auth::logout();
if(Auth::attempt(array('nim' => Input::get('nim'),'password' => Input::get('password'),'verified' => 1))){
return Redirect::route('home-view');
}
else{
return "Your Account not verfied. Please wait until admin verified your account or contact your admin";
}
}
else{
return "NIM/Password wrong";
}
there was no problem, but I think I need other solution so Auth don't need to Login(Attempt) Twice
You can use the validate method. This would work:
public function postSignIn(){
if(Auth::attempt(array('email' => Input::get('email'),'password' => Input::get('password'),'verifiedFlag'=>1))){
return Redirect::route('home-view');
}
elseif(Auth::validate(array('email' => Input::get('email'),'password' => Input::get('password')))){
return "Your Account not verified by Admin";
}
else
{
return "Email/Password wrong";
}
}
Filters are the way to go. It's easy and clean to solve this problem, see my example below.
if user is inactive at any point it will logout user,
you can redirect user with Session flash message, your login code works as it is.
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
return Redirect::guest('login');
}
}
else
{
// If the user is not active any more, immidiately log out.
if(Auth::check() && !Auth::user()->verifiedFlag)
{
Auth::logout();
Session::flash('message','Your account is not active, please contact your administrator to active your account');
// redirect to login page
return Redirect::to('/');
}
}
});
Hello i create website in laravel but i facing one problem. The problem is that when user is not log in and user type www.test.com/notifications that time showing error like this
ErrorException (E_UNKNOWN)
Undefined variable: messages (View: /home/test/app/views/message-page.blade.php)
But i want to when user is not log in and enter www.test.com/notifications so user automatic redirect to index page. Please help me i very confuse.
I using the some code in base controller is as follows:
public function checkLoggedIn(){
if(Auth::user()->check()){
return;
}
else {
return Redirect::to("/");
}
}
You should do it this way:
public function checkLoggedIn(){
if (!Auth::check()) {
return Redirect::to("/");
}
return true;
}
However I assume you want to use this function in another controller so then you should do it this way:
$result = $this->checkLoggedIn();
if ($result !== true) {
return $result;
}
to make redirection.
But Laravel have filters so you can easily check if user is logged.
You can just use in your routes.php:
Route::group(
['before' => 'auth'],
function () {
// here you put all paths that requires user authentication
}
);
And you can adjust your filter in app/filters for example:
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
return Redirect::to('/');
}
}
});