See profile other users in FOSUserBundle - fosuserbundle

first, sorry for my english .
I have a site with an ad system.
Thanks to FOSUserBundle, access to his profile is very simple.
But I would like to make the profile of other users public.
Let me explain, I would like us to click on the name of a user to see his profile.
When I dump users, I have two distinct users :
app.user that returns the current user and ad.user that returns the user who wrote the ad.
Unfortunately when I click the user who created the ad, it automatically sends to the profile of the current user :'(
I looked for a lot of solutions but nothing works, the ad.user continues to return the current user despite a url that indicates the id of the author of the ad.
I am on symfony 3. Please help me.
Dump of app.user =
User {#405 ▼
#id: 1
#ville: "Angers"
#description: "Test description dans profil Modifé TEST 2!!"
-ads: PersistentCollection {#450 ▶}
-comments: PersistentCollection {#475 ▶}
#username: "superadmin"
#usernameCanonical: "superadmin"
#email: "superadmin#gmail.com"
#emailCanonical: "superadmin#gmail.com"
#enabled: true
#salt: null
#password: "$2y$13$lSKxx9k4ctd5BNBDEoCEGeHU1jHi7S8jD7o8jS01S1TNX/KK8.zH."
#plainPassword: null
#lastLogin: DateTime #1525031449 {#400 ▶}
#confirmationToken: null
#passwordRequestedAt: null
#groups: null
#roles: array:1 [▶]
}
Dump of ad.user =
User {#740 ▼
+__isInitialized__: true
#id: 2
#ville: "Angers"
#description: null
-ads: PersistentCollection {#1057 ▶}
-comments: PersistentCollection {#1074 ▶}
#username: "usertest"
#usernameCanonical: "usertest"
#email: "usertest#gmail.com"
#emailCanonical: "usertest#gmail.com"
#enabled: true
#salt: null
#password: "$2y$13$3RhGWDCHt/uQn2EvLhuQ0es8dNOuwXhgiU/gtRKc3CzhQ7iWB.VUm"
#plainPassword: null
#lastLogin: DateTime #1525008711 {#1048 ▶}
#confirmationToken: null
#passwordRequestedAt: null
#groups: null
#roles: [] …2
}
Is it possible that there is a priority somewhere that forces access to the profile of the current user ?
My code in twig :
Publiée par : {{ ad.user.username}} <span class="text-secondary">le {{ ad.date|date("d/m/Y") }}</span>
Thank you

I FOUND !!!!!!
in ProfileController i add a new showIdAction:
/**
* #Route("/profile/{id}", name="profile_id", requirements={"id"="\d+"})
*/
public function showIdAction($id)
{
$user = $this->getDoctrine()
->getRepository('AppBundle:User')
->find($id);
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('#FOSUser/Profile/show.html.twig', array(
'user' => $user,
));
}
And, in profile.xml ( routing of FOSUserBundle) i add a new route:
<route id="profile_id" path="/{id}" methods="GET">
<default key="_controller">fos_user.profile.controller:showIdAction</default>
</route>
In twig :
<a href="{{ path('profile_id', {'id': ad.user.id }) }}
And its WORK .
I leave here the question if ever others seek a solution

Related

Cakephp authentication plugin how can I add difference session key?

In present scenario after login in front end if I visit /admin prefix. It's accessing admin panel. Here I'm using difference model for login. For front end I'm using users table and for admin I'm using admin_users table. I have made this changes in application.php like
if($request->getParam('prefix') == 'Admin')
{
$identifierSettings += [
'resolver' => [
'className' => 'Authentication.Orm',
'userModel' => 'AdminUsers',
],
];
}
How could I add difference session key for admin and front-end ?
In Authentication.Session
Set your session key for admin 'sessionKey' => 'Auth.admin'
Note : Default sessionKey is Auth
Details : https://book.cakephp.org/authentication/2/en/authenticators.html#session

Yii2 SaaS Authentication

I'm Developing SaaS application using Yii2 with separate DB architecture. I have a problem in login to system by using tenant database.
I need to get tenant database details from common db and establish tenant db connection after entering company id, username and password in login form.
This is my index.php file.
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/_protected/vendor/autoload.php');
require(__DIR__ . '/_protected/vendor/yiisoft/yii2/Yii.php');
$config = require(__DIR__ . '/_protected/config/web.php');
(new yii\web\Application($config));
if (Yii::$app->session->get('company')) :
$appConnection = \app\models\Userdbconnections::find()->where(['company_id' => Yii::$app->session->get('company')])->one();
\Yii::$app->dbDynamic->dsn = "mysql:host=localhost;dbname=$appConnection->dns";
\Yii::$app->dbDynamic->username = $appConnection->user;
\Yii::$app->dbDynamic->password = $appConnection->password;
\Yii::$app->dbDynamic->charset = 'utf8';
endif;
Yii::$app->run(); // this will run the application
?>
From login function after post logging data, auth controller is like this
if ( Yii::$app->request->post() ){
$connection = \app\models\Userdbconnections::find()->where(['company_id'=>Yii::$app->request->post('LoginForm')['company']])->one();
$_SESSION["dsn"] = $connection->dns;
$_SESSION["user"] = $connection->user;
$_SESSION["pass"] = $connection->password;
$_SESSION["company_id"] = $connection->company_id;
// Yii::$app->db()->close();
Yii::$app->set('db', [
'class' => '\yii\db\Connection',
'dsn' => "mysql:host=localhost;dbname={$connection->dns}",
'username' => $connection->user,
'password' => $connection->password,
]);
$model_db = new LoginForm();
$model_db->load(Yii::$app->request->post());
$model_db->login();
$_SESSION["login_user"] = $model_db->username;
}
User Management Module called in web.php under component part as following
'user' => [
'class' => 'webvimark\modules\UserManagement\components\UserConfig',
// Comment this if you don't want to record user logins
'on afterLogin' => function($event) {
\webvimark\modules\UserManagement\models\UserVisitLog::newVisitor($event->identity->id);
},
'enableSession' =>true,
],
Each model file consist with following code
public static function getDb()
{
return Yii::$app->get('dbDynamic');
}
So now i'm able to log from tenant db. But after checking i noticed User Management part, creation, role creation all these linked to common db when ever i logged in to tenant db. Is there anything I misses in here?
One way to do it is having two connections. One connection for common details coming from common database (user details, tenant db he belongs to, et al). This connection is static, so must be defined in the config (or just rename what comes with Yii Basic app to something like commonDb or use it with just db name.
Another one will be connected to the specific user tenant database. This will be dynamic and details must change. There are many ways to do it. One is to defined it before app runs. See this forum post for details. Another would be setting it up before request using Yii Container and call it inside your models et al. There might be other ways too.
So the process goes like this
User logs in. Connection used is the common connection (let it be defined as Yii::$app->db).
Using details from (1) create the dynamic connection.
Use the connections where needed (in models, Active data providers or Query builders)
Here is untested example
//common database with user login
----------------------------------
| id | name | tenant_database |
----------------------------------
| 1 | Stef | company_a |
----------------------------------
Note here that Yii::$app->user->identity will hold model class that wraps this table
//config/web.php
return [
'components' =>[
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=common_db',
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
]
'userDb' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=${database}',
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
]
]
//set it up before request
'on beforeRequest' => function ($event) {
if(Yii::$app->user->isGuest)
{
// redirect user to Login page
}
else
{
$currentDSN = Yii::$app->userDb->dsn;
$tenantDB = Yii::$app->user->identity->tenant_database;
Yii::$app->userDb->dsn = str_replace('${database}', $tenantDB, $currentDSN);
}
},
]
Then in model class override getDb as follows
class Data extends \yii\db\ActiveRecord
{
public static function getDb()
{
return Yii::$app->userDb;
}
}
Then user it as in:
$data = Data::find()->all();
$data = Yii::$app->userDb->createCommand('SELECT * FROM data')->queryAll();
UPDATE
Since OP wants the data to be in tenant db, the only way is having each tenant to have special Tenant Code, and on login page you will provide inputs for Tenant Code, Username and Password. Then
1. Query the common table for the database name associated with that code
2. Change Connection details as shown above
3. Login with TenantLogin class that uses tenant connection as shown above with Data class.
The new common table
----------------------------
| code | tenant_database |
----------------------------
| 12333 | company_a |
----------------------------

Laravel 4.1 authentication session data not persisting across requests

I have a Laravel 4.1 app using the eloquent authentication driver and the database session driver. My authentication controller is successfully running Auth::attempt and redirecting to a new page. However, once on the new page the authentication session data seems to be gone. I have an auth filter running on the redirected-to page and it fails, which then redirects the user to the login page again. The user never gets past the login page.
Here is my session.php:
<?php
return array(
'driver' => 'database',
'lifetime' => 120,
'expire_on_close' => true,
'files' => storage_path().'/sessions',
'connection' => 'mysql',
'table' => 'sessions',
'lottery' => array(2, 100),
'cookie' => 'laravel_session',
'path' => '/',
'domain' => null,
'secure' => false,
);
My sessions table schema:
CREATE TABLE `sessions` (
`id` varchar(32) NOT NULL,
`payload` text NOT NULL,
`last_activity` int(11) NOT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
And my auth filter:
Route::filter('auth', function()
{
if (Auth::guest()) {
if ( Request::ajax() ) {
return Response::make("Your session has timed out. Please sign in again.", 401);
} else {
return Redirect::guest('login');
}
}
});
The Auth::guest() call in the auth filter always returns false.
I added some Logging to the user() method of Illuminate/Auth/Guard.php and found that in the POST from the login form, the authentication data was in the session when the user() method was called. However, when it is called from the auth filter on the redirect (Auth::guest() indirectly calls the user() method), the session data is gone.
Here is the user() method, for reference:
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
$id = $this->session->get($this->getName());
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
$user = null;
if ( ! is_null($id))
{
$user = $this->provider->retrieveByID($id);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
// pull the user data on that cookie which serves as a remember cookie on
// the application. Once we have a user we can return it to the caller.
$recaller = $this->getRecaller();
if (is_null($user) && ! is_null($recaller))
{
$user = $this->getUserByRecaller($recaller);
}
return $this->user = $user;
}
When user() is called from the auth filter, $this->loggedOut is false, but $this->user is null and $this->session->get($this->getName()) returns null.
It does not appear that Auth::logout() is being called at any point.
The id field of the sessions table needs to have a length of at least 40 because Laravel uses a sha1 hash as the session id.
I had a similar issue where the session was not persisting between requests when I deployed my site to a digital ocean instance and I spent a few days searching for an answer to fix this issue since the site was working fine in a local vagrant machine.
The solution to my problem was that on the User model I had to change the getAuthPassword function return statement from "$this->password" to "$this->Password" which it is the column name in the database.
public function getAuthPassword()
{
return $this->Password;
}

Extending cakephp auth component with extra conditions

Problem: I want to show different error messages to user based on user status on login (using ajax). For ex: If the user status is pending, I want to show one message, or else if the user status is disabled, I want to show another message. Only active user should be able to login.
After some searching found that I can use
identify method
or
I should use write my conditions inside "if
($this->Auth->login())" condition in my login method.
If I use 1st method in custom component (which will extend auth), hope it can only return true or false, right ? Can it set error messages and return, so that I can get it from my controller ?
If I use 2nd method after allowing the user to login I should check the status and if it is not active, I should remove the login credentials from Auth/Session. how can I do that ? Is this a good method ?
Any other better solution ? Im using cakephp2.0
I would create a class extending from BaseAuthenticate for your users and set this up within your AppController.
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => ..... ,
'logoutRedirect' => ..... ,
'loginAction' => ..... ,
'authenticate' => array('YourUsers'),
)
);
And then create the class
<?php
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
class YourUsersAuthenticate extends BaseAuthenticate {
public function authenticate(CakeRequest $request, CakeResponse $response) {
// your code goes in here
}
}
You can return false from within the authenticate to deny the user access or can return an object on success that will get stored in $this->Auth->user which you can interogate later.
If you get stuck, the CookBook has a lot of detail about this.

CakePHP multi-model view

I am creating a website in CakePHP and I am kind of new on it. I couldn't find good resources on this matter, so there you go:
I have a three table structure for registering users: Users, Addresses and Contacts. I have to build a view with info of all three tables like:
Full Name: [ ] (from Users)
Shipping Address: [ ] (from Address)
Mobile Phone: [ ] (from Contact)
e-Mail Address: [ ] (from Contact)
What is the best way to deal with this situation. Specially for saving. Creating a new Model to represent this, that will have a save() method itself (Maybe a sql view in the database) Create a Controller to deal with this View that binds or unbinds info
I wonder still how I will handle both contacts as they will be 2 different INSERT's
Any hint or resources I can dig of I will be glad.
If your using the latest 1.2 code, check out Model::saveAll in the api
eg. Your view might look something like this:
echo $form->create('User', array('action' => 'add');
echo $form->input('User.name');
echo $form->input('Address.line_1');
echo $form->input('Contact.tel');
echo $form->end('Save');
Then in your Users controller add method you'd have something like:
...
if($this->User->saveAll($this->data)) {
$this->Session->setFlash('Save Successful');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Please review the form for errors');
}
...
In your User model you will need something like:
var $hasOne = array('Address', 'Contact');
Hope that helps!
http://api.cakephp.org/class_model.html#49f295217028004b5a723caf086a86b1
CakePHP allows you to easily maintains link between your models using relationship, see http://book.cakephp.org/view/78/Associations-Linking-Models-Together for the complete detail. Then retreiving the right User, you'll also get "for free", its address and contact informations.
3 models : User, Address, Contact
User hasOne Address, Contact
Address belongsTo User
Contact belongsTo User
in your model you define this like this :
class User extends AppModel {
var $name = 'User';
var $hasOne = array('Address','Contact');
..
To make this view, you need user_id field ind addresses, and contacts tables
To use this in a view, you simply call a find on the User model with a recursive of one (and btw, the users controller only uses User model).
$this->User->recursive = 1;
$this->set('user', $this->User->find('first', array('conditions'=>array('id'=>666)));
This will result in this array for your view :
array(
'Use' => array(
'id' => 666,
'name' => 'Alexander'
),
'Address' => array(
'id' => 123,
'zip' => 555
),
'Contact' => array(
'id' => 432,
'phone' => '555-1515'
));

Resources