HWIOAuthoBundle with FOSUserbundle. Render Controller not working - symfony

I try to render a controller in my webSite but an exception is triggered:
HERE MY CODE
render(controller("HWIOAuthBundle:Connect:login"))
HERE THE MESSAGE
An exception has been thrown during the rendering of a template ("Controller "HWIOAuthBundle:Connect:login" for URI "/_fragment" is not callable.") in MYBlogBundle::layout.html.twig at line 39
I do not understand because the route is the good one.
vendor/hwi/oauth-bundle/HWI/Bundle/OAuthBundle/Resources/Views/Connect/login.html.twig

There is no loginAction in HWIOAuthBundle's ConnectController. Please use connectAction, it will render vendor/hwi/oauth-bundle/HWI/Bundle/OAuthBundle/Resources/Views/Connect/login.html.twig template.
render(controller("HWIOAuthBundle:Connect:connect"))

Related

Can't use render(controller) in SonataAdminBundle template

I create custom controller(extending Sonata\AdminBundle\Controller\CRUDController) and action.
When render this action {{render(controller('MainBundle:SonataAdmin/Order:searchCertificate'))}}
I get Symfony error:
An exception has been thrown during the rendering of a template ("There is no _sonata_admin defined for the controller MainBundle\Controller\SonataAdmin\OrderController and the current route").
I found answer in official documentation:
If you want to render a custom controller action in a template by
using the render function in twig you need to add _sonata_admin as an
attribute. For example; {{
render(controller('AppBundle:XxxxCRUD:comment', {'_sonata_admin':
'sonata.admin.xxxx' })) }}. This has to be done because the moment the
rendering should happen the routing, which usually sets the value of
this parameter, is not involved at all, and then you will get an error
"There is no _sonata_admin defined for the controller
AppBundleControllerXxxxCRUDController and the current route ' '."
i have solved this Problem by setting the _sonata_admin in the comming request:
with normal Controller:
$request->request->set('_sonata_admin','admin.template');

Symfony2 app.request.get('_route') is empty when throw new AccessDeniedException

I'm working on implementing a ROLE based admin application. I have a custom voter and at some point I'm doing something like:
if($role && VoterInterface::ACCESS_GRANTED !== $voteResult) {
throw new AccessDeniedException('Unauthorized access!');
}
and the result is that a custom error403.html.twig template is rendered.
So far so good.
The error403 template extends the main template in which at some point I'm building a menu using app.request.get('_route') for generating the links.
The problem is app.request.get('_route') is null.
xDebug-ing the issue I've noticed that somehow the $request->attributes->parameters array does not contain _route or _route_params keys.
Any thoughts?
The problem is Symfony uses sub-request for rendering error pages. It doesn't need a router and you have not exatly the same request object as in master request.
Github issue
https://github.com/symfony/symfony/issues/5804
Same question on SO
app.request.attributes.get('_route') is empty when I override 404 error page
Some theory
https://knpuniversity.com/screencast/symfony-journey/sub-request-internals
You can write your own exception listener and modify this behaviour in some way.

Symfony 2 : HWiOauthBundle : Overriding connect_success.html.twig

I have implemented both FOSUserBundle and HWIOauthBundle in my Symfony 2 project. Basically, everything works fine but I would like to customize a litle bit more. Typically I use the connect functionnality of the HWIOauthBundle to connect oauth account to user already connected with the authentication form (FOSUserBundle).
In case of succes, the controller action HWIOAuthBundle:Connect:connectService displays the twig template connect_success.html.twig. At this point, I would like to override this template and do the following actions :
Create a flash message
Display the flash message on my homepage
You can obtain this behavior easily with FOSUserBundle as this bundle dispatchs many events to hook into the controllers. But with HWIOauthBundle this is not possible.
My solution is the following :
1/ I override connect_success.html.twig by placing the same named file in app/Ressources/HWIOauthBundle/views/Connect with the following code:
{{ render(controller('MyUserBundle:User:HWIOAuthFlash')) }}
2/ In my user controller (MyUserBundle:User), I create an action HWIOAuthFlashAction() that defines a flash message and forwards to the controller action that displays he homepage(MyMainBundle:Main:homepage)
public function HWIOAuthFlashAction()
{
// Here : flash message definition
return $this->forward('MyMainBundle:Main:homepage');
}
At this point the homepage is displayed with the flash message. But I had to remove two links in the homepage template (homepage.twig.html)that permits the user to switch between two locales.
The following code is the one that I had to remove from my template :
<ul>
<li>FR</li>
<li>EN</li>
</ul>
I understand that that the special variable _route is null. And I get the following message :
An exception has been thrown during the rendering of a template
("Error when rendering
"xxxxx/web/app_dev.php/connect/service/google?key=yyyyyyy" (Status
code is 500).") in HWIOAuthBundle:Connect:connect_success.html.twig at
line 3.
I have two questions :
To achieve my goal, is it the good way ?
How to say to symfony that I want my route to be homepage ?
As proposed in my comment, here is my solution :
In my homepage template homepage.twig.html :
{% set route = app.request.get('_route') ? app.request.get('_route') : 'homepage' %}
<ul>
<li>FR</li>
<li>EN</li>
</ul>

How to include Web Debug Toolbar in Symfony Response?

When I render a template and return a Response from a Controller, there is a nice Web Debug Toolbar on the bottom of the page.
Is it possible to make this bar appear when I don't use template and return a response by creating a Response object myself?
It should be sufficient to make sure there is a valid <body>...</body>-block contained in the response-HTML-code. if the body-section is missing, then the debug toolbar won't appear.

If a user doesn't have permission to render a View (configured on configure.zcml), how do I raise Forbidden instead of redirecting to login_form?

I have a browser view, with some utilities. Is mainly an "utility view" that I traverse using old-style pt templates (that are inside skins folder). My browser/configure.zcml:
<browser:page
for="*"
name="my_view"
class=".myview.MyView"
allowed_interface=".myview.IMyView"
permission="my.permission"
/>
As you can see, it has a custom permission: this is needed because anonymous users can't render this view and this permission is really specific to a certain situation in my portal.
I thought: I'm going to try to render the view in my template.pt: since I've already set a permission in browser/configure.zcml, when trying to render Plone itself is going to handle this for me. So I did in my template
<span tal:define="my_view here/##myview">
</span>
So far, so good. A user without my.permission trying to get into /Plone/template.pt will fail. But Plone redirects to the login form, and I would prefer to raise a Forbidden exception instead. Something like:
<span tal:define="my_view here/##myview | here/raiseForbidden">
</span>
...but, of course, this doesn't work since the view rendering didn't throw an error. (I know here/raiseForbidden doesn't exist, it's here/raiseUnauthorized that is usually used but the concept is the same)
My question is: is it possible to do it? Configuring my permission somewhere, or configuring some method in my view (like render or __call__), that when a user doesn't have permission to render it, an exception like Forbidden is raised?
Plone redirects to the login form because you raise Unauthorized. If you want different behaviour you'll need to do something different.
In this case, you could directly redirect the user to a new page with an error message tailored to the situation.
actually you don't need to do this:
"tal:define="my_view here/##myview>"
because for browser views there's a default variable named "view" that already contain your class.
For raising an exception you should remove permission check from the zml directive and modify your class as below:
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from AccessControl import getSecurityManager
from AccessControl import Unauthorized
class YourBrowserView(BrowserView):
""" .. """
index = ViewPageTemplateFile("templates/yourtemplate.pt")
...
def __call__(self):
if not getSecurityManager().checkPermission(your.permission, self.context):
raise Unauthorized("You are not authorized! Go away!")
else: return index()
Bye
Giacomo

Resources