Separate frontend and backend users with sfDoctrineGuardPlugin - php

i'm starting a project adn i'm using symfony, my first time with symfony, really great actually, i already install the sfDoctrineGuardPlugin and everything is ok untill now, why?, because frontend users can login in the backend and vice versa, i dont't want that, so, i start to google, i found Symfony sfDoctrineGuardPlugin custom login query here in SO, but i don't know where i should place the function so, i haven't tested it.
As i don't want frontend users can login in the backend, i think i can use credentials, can i?? but, symfony check for users credentials after they are logged, and i don't want tha neither, so, how can i achieve this?, maybe if i could have namespaces in the session, i can check if an admin in the backend namespace and also for frontend users, so they never get fixed, i think.
I don't know really know if sfDoctrineGuardPlugin have some configuration that can manage this situation, exist such a config??
Also, in my backend, i will like to have a page to manage the frontend users, and other for backend users, because frontend users will have a profile and addresses, think this is much easier, but i don't know where to start.
need some help over here
thanks

After a few days coding, i was able to do it exactly as i wanted, i'm going to share my solution:
I started with an example i found here in SO, you can read the post here:
Symfony sfDoctrineGuardPlugin custom login query
it gave me an idea and i executed it, so, i create \lib\Util.class.php, with to functions, one for query backend users and another for frontend users
static public function retrieveCustomer($username, $isActive = true)
{
$query = Doctrine_Core::getTable('sfGuardUser')->createQuery('u')
->leftJoin('u.Groups g')
->leftJoin('g.Permissions p')
->where('u.username = ?', $username)
->addWhere('u.is_active = ?', $isActive)
->addWhere('g.name = ?', 'customers');
return $query->fetchOne();
}
static public function retrieveAdmin($username, $isActive = true)
{
$query = Doctrine_Core::getTable('sfGuardUser')->createQuery('u')
->leftJoin('u.Groups g')
->leftJoin('g.Permissions p')
->where('u.username = ?', $username)
->addWhere('u.is_active = ?', $isActive)
->whereIn('g.name', array('administrators','operators'));
return $query->fetchOne();
}
Now, in the app.yml of each app, i override the default query of the plugin
#Example for apps/backend/config/app.yml
all:
sf_guard_plugin:
retrieve_by_username_callable: Util::retrieveAdmin
untill now all was good, but i started to face another problem, so i open a new thread:
Overwriting isAuthenticated() in symfony and there i got the final step for my solution, that was setting differents session name for each app, so, in the factories.yml of each app:
#apps\backend\config\factories.yml
storage:
class: sfSessionStorage
param:
session_name: backend
and now all is set, frontend users can not log in in backend app and vice versa.
feel free to comment

The most common approach is through credentials, my backend applications security.yml looks like:
all:
is_secure: on
credentials: [login_backend]

Related

Is it possible in LARAVEL to tag a user as logged in when getting his username from a custom URL?

I am currently doing a website wherein the login URLs are varying and displays the data according to the assigned projects to them.
For example, user A can only access www.example.com/projects/proj1. This is the homepage for user A and if he logs in he uses www.example.com/projects/proj1/login
While user B can only access www.example.com/projects/proj2. This is the homepage for user B and if he logs in he uses www.example.com/projects/proj2/login
Please note that proj1 and proj2 are varying depending on the database. So I have to check first that these projects are already registered in the database.
I am thinking of having a route like this.
For web.php
Route::get('/projects/{project_name}', 'PageHandler\CustomPageController#projects');
Route::get('/projects/{project_name}/login', 'PageHandler\CustomPageController#login');
Route::put('/projects/{project_name}/auth/{user}', 'PageHandler\TestUserPageController#auth');
Then my customepagecontroller.php looks like this
class CustomPageController extends Controller
{
public function projects(string $projectName)
{
if (auth()->user() == null)
return redirect('/projects'. '/' . $projectName . '/login');
}
public function login(string $projectName)
{
return view('login')->with('projectName', $projectName);
}
public function auth(Request $request, string $projectName)
{
$username = $request->username;
//How to set $username as logged in?
// rest of the code to show the home page after authentication
}
}
login.blade.php basically just looks like a form submitting username and password and calling auth of CustomPageController with a string parameter for the URL
So my question is how can I set $username as logged in already using the Auth of Laravel? Or should I create my custom Authentication Controllers?
Now, this is the only approach I have in mind for me to enable the logging in of users to varying URLs. Please let me know if you have better approach.
Thank you!
If you only want to limit the project the users can access, I do not see a need to use 2 different login URLs (please correct me if there is a reason why you want different URLs for that), instead, you simply find which project the user belongs to from the database.
For authentication, Laravel allows you to implement authentication in a very easy way, you can refer to the documentation. Using Laravel's authentication would be easier and safer than writing your own one, and even if the default functionalities it provides may not be exactly the same as those you would want to achieve, you can still add your own things, which is still a lot easier than implementing it from scratch.
As for setting a user as logged in with Laravel's authentication services, you can use Auth::login($user);. Here, $user must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract. You can refer to this part of the documentation for more details.

Using user plugin session in another plugin within OctoberCMS

I’m new to Laravel and OctoberCMS, there is a lot of documentation on both but because I don’t have much of an understanding of either I would really appreciate some help. It's also quite confusing trying to understand both at the same time, especially as there is way more documentation about laravel than October.
Currently, I wish to extend a plugin (Link to their extending plugin documentation). I need to use the session (username or email) from the rainlab user plugin (Link to their Git) and insert it into another plugin.
I'm upgrading the other plugin that currently relies on users entering their name via a form and replacing this with their username or email address once logged in.
My Layout contains the user plugin session:
{% component 'session' %}
The user plugin session works fine on the rest of my pages but I have gotten a 'value not found' error with my previous attempts using it with the plugin.
I know I need to either link the plugins or create a new one, and retrieve the username (or email) from the users database and insert it into another table, just can’t quite work out how to do this. To make matters worse I don’t have experience with MVC either!
Added this function (from an example I found) to the second plugin's Plugin.php page:
Plugin.php
public function boot()
{
Event::listen('rainlab.user.register', function($user) {
// Code to register $user->email to mailing list
});
}
But I got 'Undefined' error.
I've also tried adding a Routes.php file as I thought there may be an issue with middleware.
Routes.php
Route::get('/test', function () {
dd(
Auth::getUser(),
BackendAuth::getUser()
);
})->middleware('web');
Received this error:
"Call to undefined method RainLab\User\Facades\Auth::getUser()"
I’ve been banging my head against the wall for a week now and any tips or explanations would be greatly received. If you require any other bits of code please let me know. I haven't added any more bits of code as I know those pieces didn't work (being going around in circles and it would be a bit erratic and not much use) and I don't want to spam code on this page. I've shown the bits above to try and explain some previous thought processes. Also, it's the start of my project and not much code has changed from the generic code available to you from the OctoberCMS and User Plugin Gits.
I believe an explanation and some help here would benefit a lot of people, I can see I’m not the only one to have issues, partly down to the changes in the latest version of laravel.
Any thoughts and explanations would be much appreciated.
UPDATE:
To make it clearer where I need my session to appear I've included the code below. $name needs to be replaced by a new variable like email or username (from session).
components\Chat.php
$name = 'anonymous';
if ($n = Input::get('name')) {
$name = strip_tags($n);
}
$message = new Message(['text'=>$text, 'user_id'=>$user_id, 'name'=>$name]);
$message->save();
return $this->getMessagesOutput($message->id, [$message]);
}
It will be really Easy if you are adding session in layout {% component 'session' %}
now on entire page you can use {{ user.email }} directly in twig to get user email
if you need to use using PHP you can use Auth facade
this code must me in component which are included in page which is using that layout or in its life-cycle methods
// Returns the signed in user
$user = Auth::getUser();
echo $user->email;
you can not directly use route because route is separate from page execution so Auth will not work there.
"I need to use the session (username or email) from the rainlab user plugin (Link to their Git) and insert it into another plugin."
just create new component which have this code and include it in page.
can you share details what you need to do and how you are doing to get details and on which time you need to use that details so i can answer it precisely.
UPDATE
// by default name
$name = 'anonymous';
$user_id = 0; // if user is not logged in
// if user is logged in then use session
if($sessionUser = \Auth::getUser()) {
// if user didn't set name then you can assign some default value here or email
$name = $sessionUser->name != '' ? $sessionUser->name : $sessionUser->email;
$user_id = $sessionUser->id;
}
// not needed but if user want to edit its name then we use that one
if ($n = Input::get('name')) {
$name = strip_tags($n);
}
$message = new Message(['text'=>$text, 'user_id'=>$user_id, 'name'=>$name]);
$message->save();
return $this->getMessagesOutput($message->id, [$message]);

How can I properly authenticate a user as an admin in Laravel?

I am attempting to introduce "ghosting" into my application - wherein I can access our app from the POV of a user.
Currently using the loginUsingID function to achieve this, with a protected route only accessible by admins. However, I would also like to display to the admin that they are ghosting a user by displaying a bar across the top of our app.
I was thinking of adding a property to the user is_being_ghosted - setting it as false on logout, false on login, and true on ghostLogin.
But I realize there is a small chance an admin attempts to ghost a user, and it sets that property, and while they are investigating things within the account, the user themselves refreshes their page (they were already authenticated so do not need to login again). In that case they would see this "admin bar" across the top, which clearly I wouldn't want to happen.
Is there an efficient way to achieve what I'm trying to do here? Am I going about this the wrong way?
As jszobody has mentioned. You could rather manage the state inside the session. You secure the /ghost route and then if the original-user-id session is set you display your bar and an unghost link.
public function ghost(Request $request, $id)
{
$request->session()->put('original-user-id', Auth::user()->id);
Auth::loginUsingId($id);
return redirect('/');
}
public function unghost(Request $request)
{
if ($request->session()->has('original-user-id')) {
Auth::loginUsingId($request->session()->pull('original-user-id'));
}
return redirect('/');
}
Update:
The ghost endpoint basically accepts the id that you want to impersonate, typically found through an ajax search input or something similar. Whatever suites your use case.

How do I get the user role using Zend framework2?

I am using Zend Framework 2 and having trouble getting the user role. I am using zfc user and Zfc Rbac. The roles currently work however I would like to get the values to use in an if statement (in the controller). What is the function to call these? I have the developer tool turned on so I can see the role assigned but can't figure out out to call it.
Thanks
Matt
If you have setup you identify correctly in ZfcRbac, then you can use the authorization service (ZfcRbac\Service\AuthorizationService) to get the identity and its roles.
$authorizationService->getIdentity()->getRoles();
I was used the below code and was able to get the role of the logged in user.
$viewmodel = new ViewModel();
$authorize = $this->getServiceLocator()->get('UserRbac\Identity\IdentityRoleProvider');
$roles = $authorize->getIdentityRoles();
echo $roles[0];
$viewmodel->setVariable("roles", $roles);
return $viewmodel;

CakePHP redirect on login depending on username

I have a CakePHP 1.3 application that has a login system, which works well. It uses a DB with a users table, which existed before creating this app.
I'm using Auth in my AppController. The login function looks like
function login() {}
and it's located in the users_controller.
Everything works fine, as I said, but I have problems trying to add a new functionality. I would like to, during the login process, detect if a user has introduced a specific combination of login/password (let's say admin/adminpwd). If so, the login should be succesful AND he would be taken to an admin area (/admin/index). Otherwise, the login process should work as usual.
Once in this admin area (controlled by an admin_controller), this user should be able to perform some actions exclusive to him, no to the rest of users (even if they type on the browser /admin/action).
I've read about ACL, and probably it would help with this, but it seems too complicated for what I really need. Is there any simple way to do this? I guess I should modify the login function, but I don't really know how exactly, and if there's anything else I should change... any ideas?
Yeah, ACL is pretty complicated (and powerful). But in your case, I'd suggest create a 'group' field in users table to distinguish the role of the user. So you can have more admins later if you want. It's more flexible than hard-code a certain login credential in your users_controller.
There are several things you need to do to:
Tell the Auth component to transfer control to you after the user logins, so you can determine their group and redirect them accordingly.
Check if a user in a group is accessing some other group's action: If you don't, a regular user just need to be logged in, and they can type in admin url (if they know about it) and they can do everything an admin can. This check will probably be done in before_something_() in app_controller or tap into Auth somewhere.
I don't remember all the details, but you can get everything you need in the Cake Cookbook. Good luck!
Let's just see some code...
class UsersController extends AppController {
// we're moving the variable to AppController!
public function login() {
$usrInfo = $this->Auth->user();
if (isset($usrInfo) {
// this index name might not be right. I'm going off memory please check this!
if (in_array($usrInfo['username'], $this->adminUsers)) {
// do your code here for admin users.
// could be a redirect or just changing the layout used
} else {
// is a user that is logged in but not in our admin list
}
}
}
To test if the user is logged in you would need to do something like the following:
class AppController extends Controller {
protected $adminUsers = array('joe_blow_uname', 'jane_blow_uname');
public function beforeFilter() {
$routing = Configure::read('Routing.admin');
$usrInfo = $this->Auth->user();
if (isset($this->params[$routing]) && isset($usrInfo)) {
if (!in_array($usrInfo['username'], $this->adminUsers)) {
// do code here for non-admin users using /admin prefix
}
}
}
}
Let me know if this doesn't help.
Or worse breaks something...
Edit:
This is really not the best way to do this obviously. ACL or setting up some kind of group in your database would probably be better. BUT, it is a relatively quick-n-dirty way that, for a small site, should work fine.

Categories