Access $app or $request in Eloquent using Slim Framework - eloquent

I am building a Slim Framework 4 Api Application, with Eloquent.
public/index.php
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule->addConnection($dbconfig);
$capsule->setAsGlobal();
$capsule->bootEloquent();
$app->add(new RequestUser()); // for calling middleware that adds user
Middlware
class RequestUser
{
public function __invoke(Request $request, RequestHandler $handler): Response
{
....................
$user = User::where('emailid', $email)->first();
$request = $request->withAttribute('user', $user);
$request = $request->withAttribute('token', (string) $exploded_authorization[1]);
return $handler->handle($request);
}
}
Controller
use Psr\Http\Message\ServerRequestInterface as Request;
public function create(Request $request, Response $response, $args)
{
$user = $request->getAttribute('user'); // gives me the request user information
}
Model
<?php
namespace App\Models\TableModel;
use Illuminate\Database\Eloquent\Model;
use DateTime;
use Psr\Http\Message\ServerRequestInterface as Request;
class Details extends Model
{
protected $table = 'my_table';
protected $primaryKey = 'Id';
public $timestamps = false;
protected $fillable = [];
protected $hidden = [];
protected $casts = [
];
protected $appends = ['can_edit', 'can_delete'];
public function getCanEditAttribute(){
$now = date('Y-m-d H:i:s');
return $this->Start_Date >= $now;
}
public function getCanDeleteAttribute(){
//request contains the user information from the middleware? How to access here
return
}
}
I want to access the $request in my Model so that i could get the user information, who is trying to access on CanDelete.

You got the wrong kind of middleware, it needs to be a routing middleware and binded to route or route group directly, not $app->add

Related

Magento 2 : Redirect external url in controller with specific header

I need to redirect to some external url with specific header from my controller.
I tried to use setHeader on my redirect object but it seems my header is not passed cause i receive a 401 response. If i do a test with a guzzle object, just to check, headers are ok.
So how can i redirect to an external url passing headers parameters in a controller ?
My code :
declare(strict_types=1);
namespace Myvendor\Mymodule\Controller\Hipe;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\PageFactory;
use \Magento\Customer\Model\Session;
class Redirect implements HttpGetActionInterface
{
/**
* #var PageFactory
*/
protected $resultPageFactory;
private $logger;
private \Magento\Customer\Model\Session $session;
private \Myvendor\Mymodule\Helper\Data $helper;
private \Magento\Framework\Controller\Result\RedirectFactory $redirectFactory;
/**
* Constructor
*
* #param PageFactory $resultPageFactory
*/
public function __construct(\Magento\Framework\Controller\Result\RedirectFactory $resultRedirectFactory, PageFactory $resultPageFactory,\Magento\Customer\Model\Session $session, \Packitoo\Hipe\Helper\Data $helper, \Psr\Log\LoggerInterface $logger)
{
$this->resultPageFactory = $resultPageFactory;
$this->logger = $logger;
$this->session = $session;
$this->helper = $helper;
$this->redirectFactory = $resultRedirectFactory;
}
/**
* Execute view action
*
* #return ResultInterface
*/
public function execute()
{
if ($this->session->isLoggedIn()){
$customerId = $this->session->getCustomer()->getId();
$token = $this->helper->getToken($customerId);
$redirect = $this->redirectFactory->create();
$redirect->setHeader('Authorization', "Bearer " . $token, true);
$redirect->setPath('https://myexternalurl');
return $redirect;
}
}
}
This is off the top of my head and tbh only slightly different. Also have you tries setting a different header e.g. Content-Type to see if you ccan change anything?
public function __construct(
//...
Magento\Framework\Controller\Result $rawResultFactory,
//...
)
{
$this->rawResultFactory = $rawResultFactory;
}
public function execute()
{
if ($this->session->isLoggedIn()){
$customerId = $this->session->getCustomer()->getId();
$token = $this->helper->getToken($customerId);
$redirect = $this->rawResultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
$redirect->setHeader('Authorization', "Bearer " . $token, true);
$redirect->setPath('https://myexternalurl');
return $redirect;
}
}

Symfony2, Keep form data across redirect

How to use session for retrieving data during redirect? I am getting the error message: "exception 'Symfony\Component\Form\Exception\AlreadySubmittedException' with message 'You cannot change the data of a submitted form."
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Controller\UserController.php
/**
* Creates a new User entity.
*
* #Route("/new", name="user_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm(new UserType(), $user);
$form->handleRequest($request);
$session = $this->getRequest()->getSession();
$form->setData(unserialize($session->get('userFilter')));
if ( $form->isSubmitted() && $form->isValid() ) {
$session->set( 'userFilter', serialize($form->getData()) );
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
return $this->render('MeetingBundle::user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
} // public function newAction(Request $request)
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\EventListener\ExceptionListener.php
<?php
namespace MeetingBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
//every time the Kernel throws the kernel.exception event, the function onKernelException() is called.
/* also must create service :
meeting.exception_listener:
class: MeetingBundle\EventListener\ExceptionListener
arguments: [#templating, #kernel, #router]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
*/
class ExceptionListener
{
protected $templating;
protected $kernel;
protected $router;
public function __construct( EngineInterface $templating, $kernel, Router $router)
{
$this->templating = $templating;
$this->kernel = $kernel;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$request=$event->getRequest();
$referer = $event->getRequest()->headers->get('referer');
$msg="";
$excStr=$exception->__toString(); // returns string finally!
$bdup=strpos( $excStr , 'Integrity constraint violation: 1062 Duplicate entry' );
if($bdup) {
$msg=" This username is already taken. Choose another username. ";
}
if(strlen($msg)!=0) {
// flash messsages are displayed in layout.html
$request->getSession()
->getFlashBag()
->add('Error', $msg);
}
$response = new RedirectResponse($referer); // redirect to the error page
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$event->setResponse($response);
}
}

Symfony log into by using FosRestBundle

I'm working on a API. To give User Access - for example by smartphone - I need to login users by rest.
Is there an existing module available? Actually, I'm using fosUserBundle. Maybe there is a possibility to get those two bundle work together?
The Users which will login by rest are already existing as "normal" fos users.
It would be grest if you could gomme some links, tips or hints cause I'm searching and searching and searching and for the reason that I am new in symfony it's not that easy :):)
rgrds
I use FOSUserBundle for login since a smartphone by the API.
APIBundle/Controller/UserController.php (the default route is /api)
/**
* #Post("/user/login")
* #Template(engine="serializer")
*/
public function loginAction()
{
$request = $this->get('request');
$username = $request->request->get('username');
$password = $request->request->get('password');
return $this->container->get('myproject_user.user_service')
->login($username, $password);
}
in this method, I call a personal service who manage the user's functions. (UserHandler.php)
UserBundle/Handler/UserHandler.php
class UserHandler implements UserHandlerInterface
{
private $om;
private $entityClass;
private $repository;
private $container;
private $manager;
public function __construct(ObjectManager $om, Container $container, $entityClass)
{
$this->om = $om;
$this->entityClass = $entityClass;
$this->repository = $this->om->getRepository($this->entityClass);
$this->container = $container;
$this->manager = $this->container->get('fos_user.user_manager');
}
public function login($username, $password)
{
$jsonErrorCreator = $this->container->get('myproject_api.create_error_json');
$code = 0;
// check the arguments here.
$user = $this->manager->findUserByUsername($username);
if($user === null) $user = $this->manager->findUserByEmail($username);
if($user === null)
{
$code = 224;
return ($jsonErrorCreator->createErrorJson($code, $username));
}
// check the user password
if($this->checkUserPassword($user, $password) === false)
{
$code = 225;
return ($jsonErrorCreator->createErrorJson($code, null));
}
// log the user
$this->loginUser($user);
$jsonCreator = $this->container->get('myproject_api.create_json');
$response = $jsonCreator->createJson(array('success'=>true, 'user'=>$user));
return $response;
}
protected function loginUser(User $user)
{
$security = $this->container->get('security.context');
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$roles = $user->getRoles();
$token = new UsernamePasswordToken($user, null, $providerKey, $roles);
$security->setToken($token);
}
protected function checkUserPassword(User $user, $password)
{
$factory = $this->container->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
if(!$encoder)
return false;
return $encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt());
}
}
UserBundle/Handler/UserHandlerInterface.php
Interface UserHandlerInterface
{
public function login($username, $password);
}
Don't forget to declare your service !
UserBundle/Resources/config/services.yml
myproject_user.user_service:
class: %myproject_user.user_handler.class%
arguments: [ #doctrine.orm.entity_manager, #service_container, %fos_user.model.user.class%]
You can now login with your smartphone at the adresse api/user/login
I think I got the solution:
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
This seems pretty nice to me and paired with Guras inputit should work as well.

FOSUBUserProvider must implement UserProviderInterface

We are trying to use FOSUserBundle and HWIOAuthBundle together in the way like it's described there https://gist.github.com/danvbe/4476697
The only difference is that we are using mongodb. This error is fired:
User provider "wf\UserBundle\Document\FOSUBUserProvider" must implement "Symfony\Component\Security\Core\User\UserProviderInterface"
the FOSUBUserProvider is picked from this sample (the src is below). Is not it supposed that HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider implements Symfony\Component\Security\Core\User\UserProviderInterface ?
<?php
namespace wf\UserBundle\Document;
use Symfony\Component\Security\Core\User\UserInterface;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseFOSUBUserProvider;
class FOSUBUserProvider extends BaseFOSUBUserProvider
{
/**
* {#inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$property = $this->getProperty($response);
$username = $response->getUsername();
//on connect - get the access token and the user ID
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
//we "disconnect" previously connected users
if (null !== $previousUser = $this->userManager->findUserBy(array($property => $username))) {
$previousUser->$setter_id(null);
$previousUser->$setter_token(null);
$this->userManager->updateUser($previousUser);
}
//we connect current user
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {#inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$username = $response->getUsername();
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
//when the user is registrating
if (null === $user) {
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
// create new user here
$user = $this->userManager->createUser();
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
//I have set all requested data with the user's username
//modify here with relevant data
$user->setUsername($username);
$user->setEmail($username);
$user->setPassword($username);
$user->setEnabled(true);
$this->userManager->updateUser($user);
return $user;
}
//if user exists - go with the HWIOAuth way
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
//update access token
$user->$setter($response->getAccessToken());
return $user;
}
}
FOSUBUserProvider implements AccountConnectorInterface and OAuthAwareUserProviderInterface which are both interfaces so it not possible that they implement UserProviderInterface.
Checking docs in hwioauthbundle I found that OAuthUserProvider is the class that implements UserProviderInterface.
https://github.com/hwi/HWIOAuthBundle/blob/master/Security/Core/User/OAuthUserProvider.php
Using
providers:
fos_userbundle:
id: fos_user.user_manager
in 'security.yml' instead of (custom)
providers:
wf_hwi_provider:
id: wf_user.fos_user_provider
does it

Zend Framework - Passing a variable request in controller

In one of these php frameworks I've noticed a posibility to request the object Request in action as $this->request->paramName
class MyRequest extends Zend_Controller_Request_Http{
public $params = array();
public function __construct() {
$this->params = $this->getParams();
parent::__construct();
}
public function __get($name) {
if (isset($this->_params[$name])) {
return $this->_params[$name];
}
}
public function __isset($name) {
return isset($this->_params[$name]);
}
}
in MyController I've added variable request
public $request = null;
How can I change that standart Request to my one?
public function __construct(
Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response,
array $invokeArgs = array()) {
$request = new MyRequest();
parent::__construct($request, $response, $invokeArgs);
$this->request = $this->getRequest();
}
This function has given no results.
Option 1 is make method _initRequest() in bootstrap:
protected function _initRequest() {
$this->bootstrap ( 'FrontController' );
$front = $this->getResource ( 'FrontController' );
$request = $front->getRequest ();
if (null === $front->getRequest ()) {
$request = new MyRequest();
$front->setRequest ( $request );
}
return $request;
}
A bit dirty and untested solution. Would love to hear if it works.
//Bootstrap:
public function _initRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new MyRequest());
}
Try this it might help you:
in controller file
public function exampleAction(){
$result = $this->_request;
$model = new Employer_Model_JobInfo();
$results = $model->sample($result);
}
// the above line stores the values sent from the client side in $result.then sends that values to Model file with parameter $result ..
in model file
class Employer_Model_JobInfo extends Gears_Db_Table_Abstract{
public function sample($param){
$paramVal = $param->getParam('name');
$paramVal1 = $param->getParam('email');
}
}
The name and email are what name used to sent the data from client to server.