Symfony lost session on Service - session

I have a UserProvider for the Lexik bundle and check if the user exists through the session but there is a problem when I make certain request the sessions lose the value someone knows because this happens.
Service
app.user_provider:
class: ApiBundle\Security\Userprovider
arguments: ["#session","#switchconnection","#doctrine.orm.entity_manager" , "#doctrine.dbal.default_connection" , "#doctrine"]
My provider
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use ApiBundle\Entity\Utilizador;
use Symfony\Component\HttpFoundation\Session\Session;
public function __construct(Session $session,$switchconnection ,\Doctrine\ORM\EntityManager $em , \Doctrine\DBAL\Connection $dbalConnection , \Doctrine\Bundle\DoctrineBundle\Registry $doctrine) {
$this->session = $session;
$this->switchconnection = $switchconnection;
$this->em = $em;
$this->connection = $dbalConnection;
$this->doctrine = $doctrine;
}
public function loadUserByUsername($username)
{
if($this->session->get("currentuser") == $username){
$this->switchconnection->switchDatabase($this->session->get("dbconnection"), $this->connection , $this->doctrine);
$conn = $this->em->getConnection();
$stmt = $conn->prepare(".....");
$stmt->bindParam(1, $username);
$stmt->execute();
$results = $stmt->fetchAll();
$count = count($results);
if($count != 0)
{
$user= new Utilizador();
$user->setUsername($results[0]['username']);
$user->setEmail($results[0]['email']);
return $user;
}
}
throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username) );
}
I also checked that in the var/session/dev folder there is a session register with 2 Phpsession almost identical.
Update 1
Important information this only happens in webkit browsers

Please include session component in your ApiBundle\Security\Userprovider.
use Symfony\Component\HttpFoundation\Session\Session;
I think you forgot to add session component.
Update-1
User service_container by passing it in service. For me its working fine.
services.yml
app.user_provider:
class: ApiBundle\Security\Userprovider
arguments: ["#service_container", "#session","#switchconnection","#doctrine.orm.entity_manager" , "#doctrine.dbal.default_connection" , "#doctrine"]
Provider
protected $container;
protected $session;
public function __construct($container, Session $session,$switchconnection ,\Doctrine\ORM\EntityManager $em , \Doctrine\DBAL\Connection $dbalConnection , \Doctrine\Bundle\DoctrineBundle\Registry $doctrine) {
$this->container = $container;
$this->session = $container->get('session');
}

Related

Class not found in Laravel 7

I have installed a package for Laravel 7, the package in question is this http://paypal.github.io/PayPal-PHP-SDK/ to manage payments with Paypal.
I created everything, controller, web route, everything.
But the moment I go to the page to test I can't find the class.
Target class [App\Http\Controllers\PaypalController] does not exist.
PaypalController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
// use to process billing agreements
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\Plan;
use PayPal\Api\ShippingAddress;
class PaypalController extends Controller
{
private $apiContext;
private $mode;
private $client_id;
private $secret;
private $plan_id;
// Create a new instance with our paypal credentials
public function __construct()
{
// Detect if we are running in live mode or sandbox
if(config('paypal.settings.mode') == 'live'){
$this->client_id = config('paypal.live_client_id');
$this->secret = config('paypal.live_secret');
$this->plan_id = env('PAYPAL_LIVE_PLAN_ID', '');
} else {
$this->client_id = config('paypal.sandbox_client_id');
$this->secret = config('paypal.sandbox_secret');
$this->plan_id = env('PAYPAL_SANDBOX_PLAN_ID', '');
}
// Set the Paypal API Context/Credentials
$this->apiContext = new ApiContext(new OAuthTokenCredential($this->client_id, $this->secret));
$this->apiContext->setConfig(config('paypal.settings'));
}
public function paypalRedirect(){
// Create new agreement
$agreement = new Agreement();
$agreement->setName('App Name Monthly Subscription Agreement')
->setDescription('Basic Subscription')
->setStartDate(\Carbon\Carbon::now()->addMinutes(5)->toIso8601String());
// Set plan id
$plan = new Plan();
$plan->setId($this->plan_id);
$agreement->setPlan($plan);
// Add payer type
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
try {
// Create agreement
$agreement = $agreement->create($this->apiContext);
// Extract approval URL to redirect user
$approvalUrl = $agreement->getApprovalLink();
return redirect($approvalUrl);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode();
echo $ex->getData();
die($ex);
} catch (Exception $ex) {
die($ex);
}
}
public function paypalReturn(Request $request){
$token = $request->token;
$agreement = new \PayPal\Api\Agreement();
try {
// Execute agreement
$result = $agreement->execute($token, $this->apiContext);
$user = Auth::user();
$user->role = 'subscriber';
$user->paypal = 1;
if(isset($result->id)){
$user->paypal_agreement_id = $result->id;
}
$user->save();
echo 'New Subscriber Created and Billed';
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
echo 'You have either cancelled the request or your session has expired';
}
}
}
Routes
Route::get('/subscribe/paypal', 'PaypalController#paypalRedirect');
Route::get('/subscribe/paypal/return', 'PaypalController#paypalReturn');
I can't understand what the problem is! Thank you all
Just run:
composer dump-autoload
to regenerate all classes, see: https://getcomposer.org/doc/03-cli.md
Mention the Laravel 7 route:
Route::post('create_paypal_plan','App\Http\Controllers\PaypallController#create_plan');
just like this.

Access information from session in website with two different sessions

My website has two restrict areas, in the public website and admin area. I've tried to follow some instructions to make multiple sessions throughout the website, but I'm facing some problems about accessing and retrieving their information.
Below are the login methods from both pages. First from the administration area:
public function login()
{
if ($this->Admin_model->find_credentials()) {
$data['user_email'] = $this->input->post('email');
$this->session->set_userdata('auto', $data);
redirect('/admin/dashboard', 'refresh');
} else {
$this->session->set_flashdata('message', 'Desculpe, credenciais inválidas');
redirect('/admin/entrar');
}
}
And then, the admin area in the public website:
public function login()
{
if ($this->Usuarios_model->find_credentials()) {
$email = $this->input->post('email');
if ($this->Usuarios_model->is_active($email)) {
$data = array();
$data['nome'] = $this->Usuarios_model->find_col_by_email('nome_razao_social', $email);
$data['email'] = $email;
$data['tipo_usuario'] = $this->Usuarios_model->find_col_by_email('tipo_usuario', $email);
$data['id_usuario'] = $this->Usuarios_model->find_col_by_email('id', $email);
$this->session->set_userdata('auto', $data);
$this->session->set_flashdata('message', 'Bem-vindo!');
redirect('/usuario/painel');
} else {
$this->session->set_flashdata('message', 'Por favor, ative o seu cadastro');
redirect('/');
}
} else {
$this->session->set_flashdata('message', 'Desculpe, credenciais inválidas');
redirect('/');
}
}
For each new session, I am settling a name for it. Now, every point I call the session value, I must specify the name of which session I want, but I am having an error message after I try to log-in:
Message: Array to string conversion
This error points at line 161 of my model, which has the following code:
public function find_details($email = null, $id = null, $id_carro = null)
{
$this->db
->select(
'usuario.*,' .
'estado.nome_estado AS uf,' .
'cidade.nome_cidade AS cidade'
)
->join('cidade', 'cidade.id = usuario.id_cidade')
->join('estado', 'estado.id = usuario.id_estado');
if ($email) {$this->db->where('usuario.email', $email);} // 161
...
}
What do I need to do to make multiple sessions work correctly?
Alright. The solution for me was a different way to echo the value of a certain session:
$this->session->userdata('foo')['bar'].
Where foo is the session name, specified when creating a new session. In my case, a good example can be $this->session->userdata('auto')['email'];

Laravel profile edit

Alright , I have used this way to save the users info and It works perfect,
static public function memberSave($request) {
$signup = false;
$member = new Members();
$member->name = $request['name'];
$member->email = $request['email'];
$member->password = bcrypt($request['password']);
$member->save();
if (!empty($member->id)) {
$new_id = $member->id;
DB::insert("INSERT INTO roles VALUES ($new_id, 5613)");
$signup = true;
Session::flash('sm', 'Thank you! You have signed up successfully!');
}
return $signup;
}
but when making this for editing the profile(by user) It doesn't work
becuase I use new(); (making object)
I also didn't succeed to use find(); so I tried to use this
static public function saveProfile($id,$name,$email,$password) {
$sql = "UPDATE members SET name=?,email=?,password=? WHERE id=?";
$member = DB::select($sql, [$name,$email,$password,$id]);
but when I want to bcrypt the password in laravel doesnt work .
this is the code also in the second page
public function postProfile(ProfileValidation $request) {
if (Members::saveProfile($request['id'], $request['name'], $request['email'], $request['password'])) {
return redirect('');
}
}
I hope getting helped for editing the users profile by laravel , thanks.
Your Members class must extend Eloquent\Model for following this code to work.
class Members extends Model {
// optional
protected $table = 'members';
...
To find and update the member using email,
// find the single member
$member = Members::where('email', request['email'])->first();
// update the member
$member->name = $request['name'];
$member->password = $request['password'];
// now save the updated member
$member->save();
In order to to encrypt Password, Laravel provides Hash Facade,
// import this
use Hash;
...
// encrypt Password
$encrypted = Hash::make($request['password']);
...
if you want your user automatically hash the password at your model put:
public function setPasswordAttribute($value)
{
$this->attributes['password'] = Hash::make($value);
}
and you can directly check for the user if exist create new or update it:
public function saveMember($request)
{
$member = Member::findOrNew($request->email);
//All your input you want to save
$member->save();
}

How to cache model attributes in Laravel

In my current configuration, a user's email is stored on a remote server that I need to hit with a curl quest.
Luckily, I only need the email once a day when a certain process runs. However, when that process does run it will need to reference the email multiple times.
This is the current accessor I have set up for email. The problem is the curl request is being called every time I use $user->email. What's the best way to avoid this?
in UserModel:
public function getEmailAttribute(){
$curl = new Curl;
$responseJson = $curl->post('https://www.dailycred.com/admin/api/user.json',array(
'client_id'=>getenv('dailycredId')
,'client_secret'=>getenv('dailycredSecret')
,'user_id'=>$this->id
));
$response = json_decode($responseJson);
return $response->email;
}
private $cached_email = false;
public function getEmailAttribute(){
if ($this->cached_email){
// if set return cached value
return $this->cached_email;
}
// get the email
$curl = new Curl;
$responseJson = $curl->post('https://www.dailycred.com/admin/api/user.json',array(
'client_id'=>getenv('dailycredId')
,'client_secret'=>getenv('dailycredSecret')
,'user_id'=>$this->id
));
$response = json_decode($responseJson);
// cache the value
$this->cached_email = $response->email;
// and return
return $this->cached_email;
}
Depending on your use case make adjustments (ie. session, cache , static property...).
Extend a the Eloquent Model class
namespace App\Models\Utils;
use Illuminate\Database\Eloquent\Model as OldModel;
class MyModel extends OldModel
{
private $cachedAttributes = [];
public function getCachedAttribute(string $key, Callable $callable)
{
if (!array_key_exists($key, $this->cachedAttributes)) {
$this->setCachedAttribute($key, call_user_func($callable));
}
return $this->cachedAttributes[$key];
}
public function setCachedAttribute(string $key, $value)
{
return $this->cachedAttributes[$key] = $value;
}
public function refresh()
{
unset($this->cachedAttributes);
return parent::refresh();
}
}
make your class
class ElementWithEmail extends MyModel
{
const ATTRIBUTE_KEY_FOR_EMAIL = 'Email';
public function getEmailAttribute(){
$key = self::ATTRIBUTE_KEY_FOR_EMAIL;
$callable = [$this, 'getEmail'];
return $this->getCachedAttribute($key, $callable);
}
protected function getEmail()
{
$curl = new Curl;
$responseJson = $curl->post('https://www.dailycred.com/admin/api/user.json',array(
'client_id'=>getenv('dailycredId')
,'client_secret'=>getenv('dailycredSecret')
,'user_id'=>$this->id
));
$response = json_decode($responseJson);
return $response->email;
}
}
Call it from your code
$element = new ElementWithEmail();
echo $element->email;

Doctrine_Cache_Apc not works in symfony task

in my doctrine table i got this
public function countHitsFor($object_id) {
return $this->createQuery('s')
->select('COUNT(*) as count')
->where('s.target_id = ?', $object_id);
->useResultCache(true, 3600, 'hits_for_'.$object_id)
->execute(array(), Doctrine_Core::HYDRATE_SINGLE_SCALAR);
}
so if i use this from action its works fine,
first request make sql query,
second load Hits from cache
and what i want is to warm up cache from symfony task
i start task and for each object i call StatTable::getInstance()->countHitsFor($object_id) to create cache data for query, but its not works
after task first request to action makes sql query
UPD
ProjectConfiguration
public function configureDoctrine(Doctrine_Manager $manager)
{
$manager->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE, new Doctrine_Cache_Apc());
}
task
<?php
class warm_up_stat_cacheTask extends sfProgressTask
{
protected function configure()
{
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'prod'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
// add your own options here
));
$this->namespace = 'my_tasks';
$this->name = 'warm_up_stat_cache';
$this->briefDescription = '';
$this->detailedDescription = '';
}
protected function execute($arguments = array(), $options = array())
{
// initialize the database connection
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
$contextInstance = sfContext::createInstance($this->configuration);
$Objects = ObjectTable::getInstance()->findAll();
foreach ($Objects as $obj) {
StatTable::getInstance()->countHitsFor($obj->id);
}
$obj->free();
}
}
comand
php symfony my_tasks:warm_up_stat_cache
UPD2
as i understand the problem is in APC
public function countHitsFor($object_id) {
$ckey = 'hits_for_'.$object_id;
if (!apc_exists($ckey))
apc_store($ckey,$this->createQuery('s')
->select('COUNT(*) as count')
->where('s.target_id = ?', $object_id);
->useResultCache(true, 3600, 'hits_for_'.$object_id)
->execute(array(), Doctrine_Core::HYDRATE_SINGLE_SCALAR));
return (int) apc_fetch($ckey);
}
this not works too, may be APC makes prefixes for keys for different environments?
The problem is in Apc, its use separate memory spaces for Apache (mod_php) and for Cli.
I made simple key-value storage on MyISAM table.
Thanks.

Resources