I am trying to config my oauth2 server with HWIOAuthBundle and I would like to have some clarifications on what HWIOAuthBundle is expecting as response to config correctly infos_url?
I guess it is expecting a json file. So, what are its fields?
If you have links, I will be happy.
hwi_oauth:
firewall_name: main
resource_owners:
battlenet:
type: oauth2
client_id: "%client_id%"
client_secret: "%client_secret%"
access_token_url: %path%/oauth/token
authorization_url: %path%/oauth/authorize
infos_url: %path%/user/me
scope: "read"
user_response_class: HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse
paths:
identifier: id
nickname: id
realname: id
Thanks ;)
I found how it can be done! You have to create a simple API for the users as follows:
The routing:
# app/routing.yml
api_users:
pattern: /api/users.json
defaults: { _controller: AppOAuthServerBundle:User:getUser }
options:
i18n: false
The controller:
<?php
namespace App\OAuthServerBundle\Controller;
use App\GeneralBundle\Entity\User;
use FOS\RestBundle\Controller\FOSRestController;
class UserController extends FOSRestController
{
public function getUserAction()
{
$user = $this->get('security.context')->getToken()->getUser();
if ( $user instanceof User ) {
$data = array(
'id' => $user->getId(),
'username' => $user->getUsername(),
'realname' => $user->getFirstname().' '.$user->getLastname(),
'email' => $user->getEmail(),
);
} else {
$data = array();
}
$view = $this->view($data, 200)
->setTemplate('AppOAuthServerBundle:Default:index.html.twig')
->setFormat('json')
->setTemplateVar('user');
return $this->handleView($view);
}
}
Related
Hello I would like to link my forum (forum software: Woltlab) with symfony 6....
I am currently trying to do so like this:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
class DashboardController extends AbstractController
{
#[Route('/', name: 'app_dashboard')]
public function index(): Response
{
require_once('/home/maybemc-main/htdocs/maybemc.net/global.php');
$username = wcf\system\WCF::getUser()->mcName;
$id = wcf\system\WCF::getUser()->userID;
$avatar = wcf\system\WCF::getUserProfileHandler()->getAvatar()->getUrl(35);
if (!wcf\system\WCF::getSession()->getPermission('levi.perms.canSeePanel')){
header('HTTP/1.0 403 Forbidden');
die('Du hast darauf keine Berechtigung!');
}
$client = new Client();
$response = $client->get('http://**.***.***.***:8080/teamchat/messages');
$TCList = json_decode($response->getBody(), true);
return $this->render('dashboard/index.html.twig', [
'username' => $username,
'id' => $id,
'avatar' => $avatar,
'controller_name' => 'DashboardController',
'TCList' => $TCList
]);
}
}
unfortunately I get the error "Class "App\Controller\wcf\system\WCF" not found"
Do any of you have any idea why this is not working?
I also tried to add also the global.php to the service.yaml like this:
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '/home/maybemc-main/htdocs/maybemc.net/global.php'
I want intercept all errors of Symfony after that show them in JSON.
In friendsofsymfony/rest-bundle v2 I can set parameters
fos_rest:
exception:
enabled: true
exception_controller: 'App\Controller\ExceptionController::showAction'
...
But in V3 the parameter exception_controller is deleted.
My current config of FOS REST:
fos_rest:
view:
formats:
xml: false
json: true
view_response_listener: force
serializer:
groups: ['Default']
serialize_null: true
format_listener:
rules:
- { path: ^/api/v1, priorities: [ json ], fallback_format: json, prefer_extension: true }
exception:
enabled: true
Official manual say that should use handlers in JMS.
https://symfony.com/doc/current/bundles/FOSRestBundle/4-exception-controller-support.html
But it does not contain explanation how config set in yaml.
You can intercept all errors by a symfony subscriber
<?php
declare(strict_types=1);
namespace App\Util\Serializer\Normalizer;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigatorInterface;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
class CustomExceptionHandler implements SubscribingHandlerInterface
{
private bool $debug;
public function __construct(bool $kernelDebug)
{
$this->debug = $kernelDebug;
}
public static function getSubscribingMethods(): array
{
return [
[
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
'format' => JsonEncoder::FORMAT,
'type' => \Exception::class,
'method' => 'serializeToJson',
'priority' => -1,
],
];
}
public function serializeToJson(
JsonSerializationVisitor $visitor,
\Exception $exception,
array $type,
Context $context
) {
$data = $this->convertToArray($exception, $context);
return $visitor->visitArray($data, $type);
}
/**
* #return array<string, mixed>
*/
protected function convertToArray(\Exception $exception, Context $context): array
{
$statusCode = null;
if ($context->hasAttribute('template_data')) {
$templateData = $context->getAttribute('template_data');
if (array_key_exists('status_code', $templateData)) {
$statusCode = $templateData['status_code'];
}
}
$data['error'] = $this->getMessageFromThrowable($exception, $statusCode);
return $data;
}
protected function getMessageFromThrowable(\Throwable $throwable, ?int $statusCode): string
{
if ($this->debug) {
return $throwable->getMessage();
}
return array_key_exists($statusCode, Response::$statusTexts) ? Response::$statusTexts[$statusCode] : 'error';
}
}
services.yaml
App\Utils\Serializer\Normalizer\CustomExceptionHandler:
$kernelDebug: '%kernel.debug%'
I have a REST API and have an Entity Userwith field called Avatar, in DB I save name XXXX.jpg but when I return I want to add a url in this field Avatar, for example www.mylink.com/XXXX.jpg.
I'm trying with a service implements SubscribingHandlerInterfacebut I don't know how I can use it.
I have this method in this service:
class UrlManager implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return array(
array(
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'AppBundle/Entity/User',
'method' => 'serializeUrlAvatar',
),
);
}
public function serializeUrlAvatar(User $user)
{
$url = 'www.mylink.com';
return array(
"avatar" => $url . $user->getAvatar()
);
}
}
but how can I call this service to modify url when I serialize.
Now I do this:
$_format = 'json';
$json = $this->get('jms_serializer')->serialize($user, $_format);
return new Response($json, 200, ['Content-Type' => 'application/' . $_format]);
In service.yml:
app.url_converter_service:
class: AppBundle\Service\UrlManager
tags:
- { name: jms_serializer.subscribing_handler }
Update
In my controller I call this function like this:
$result = $this->get('app.url_converter_service')->serializeUrlAvatar($user);
$json = $this->get('jms_serializer')->serialize($result, $_format);
return new Response($json, 200, ['Content-Type' => 'application/' . $_format]);
So my question is, exists a way to remove the first line and serialize correctly (add the url) when I serialize?
Have you registered your service like this?
# app/config/services.yml
avatar_url_handler:
class: YourBundle\Serializer\Handler\AvatarUrlHandler
tags:
- { name: jms_serializer.subscribing_handler }
I found a solution. I create a service which implements EventSubscriberInterface like this:
class UserSerializeHandler implements EventSubscriberInterface
{
private $user_uploads;
public function __construct($user_uploads){
$this->user_uploads = $user_uploads;
}
public static function getSubscribedEvents()
{
return array(
array(
'event' => 'serializer.pre_serialize',
'class' => User::class,
'method' => 'onPreSerializeUser'
));
}
public function onPreSerializeUser(PreSerializeEvent $event)
{
/** #var User $user */
$user = $event->getObject();
$avatar = $user->getAvatar();
$user->setAvatar($this->user_uploads . "/" . $avatar);
}
}
In service.yml:
app.serializer_user_service:
class: AppBundle\Service\UserSerializeHandler
arguments: ['%user_uploads%']
tags:
- { name: jms_serializer.event_subscriber }
I have user_uploads in parameters.yml like this:
user_uploads: 'https://myUrl.com'
And in any Controller that I serialize a User, I add the url in the Avatar paramter.
$json = $this->get('jms_serializer')->serialize($user, $_format);
return new Response($json, 200, ['Content-Type' => 'application/' . $_format]);
I am using FOSElasticaBundle with symfony2 and doctrine 2.
I have trouble understanding how to retrieve actual doctrine objets from a search result. I am under the impression that it is the default behaviour but I get this kind of result :
object(Elastica\Result)[1239]
protected '_hit' =>
array (size=5)
'_index' => string 'foodmeup' (length=8)
'_type' => string 'recipes' (length=7)
'_id' => string '2' (length=1)
'_score' => float 2.2963967
'_source' =>
array (size=5)
'name' => string 'Bavaroise vanille' (length=17)
'nickName' => string 'Bavaroise vanille' (length=17)
'content' => null
'userRecipes' =>
array (size=1)
...
'tags' =>
array (size=0)
Here is my FOSElasticaBundle configuration:
#Elastic Search
fos_elastica:
default_manager: orm
clients:
default: { host: localhost, port: 9200 }
indexes:
search:
client: default
index_name: foodmeup
types:
recipes:
mappings:
name: { type: string, boost: 5}
nickName: { type: string }
content: { type: string }
userRecipes:
type: "nested"
properties:
name: { type: string }
content: { type: string }
tags:
type: "nested"
boost: 5
properties:
name: { type: string }
persistence:
driver: orm
model: AppBundle\Entity\FoodAnalytics\Recipe
repository: AppBundle\Repository\FoodAnalytics\RecipeRepository
provider: ~
finder: ~
listener: ~ # by default, listens to "insert", "update" and "delete"
And the code in my controller :
public function searchAction(Request $request)
{
$search = $request->query->get('search');
$finder = $this->get('fos_elastica.index.search.recipes');
$results = $finder->search($search)->getResults();
return array(
'search' => $search,
'results' => $results
);
}
I understood I could use a custom repository method to get the objects, but before I reach that point, what is the default way to get objects ? (Here I want a Recipe Object, an instance of my model).
Thanks a lot !
Got it!
I called the wrong service. The correct controller code to retrieve directly object instances is:
public function searchAction(Request $request)
{
$search = $request->query->get('search');
$finder = $this->get('fos_elastica.finder.search.recipes');
$results = $finder->find($search);
return array(
'search' => $search,
'results' => $results
);
}
I am attempting to use a custom handler for JMS Serializer Bundle
class CustomHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return array(
array(
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'integer',
'method' => 'serializeIntToJson',
),
);
}
public function serializeIntToJson(JsonSerializationVisitor $visitor, $int, array $type, Context $context)
{
die("GIVE ME SOMETHING");
}
}
This does nothing, and does not die. This is how I am registering the handler
$serializer = SerializerBuilder::create()
->configureHandlers(function(HandlerRegistry $registry) {
$registry->registerSubscribingHandler(new MyHandler());
})
->addDefaultHandlers()
->build();
$json = $serializer->serialize($obj, 'json');
My handler is never called and I cannot manipulate the data on serialisation.
You need to create a service for this handler:
custom_jms_handler:
class: MyBundle\Serializer\CustomHandler
tags:
- { name: jms_serializer.subscribing_handler }
Then make sure you use the registered JMS serializer service
$json = $this->get('jms_serializer')->serialize($obj, 'json');
I have this which works
$serializer = SerializerBuilder::create()
->configureListeners(function(EventDispatcher $dispatcher) {
$dispatcher->addSubscriber(new ProjectSubscriber($this->container));
$dispatcher->addSubscriber(new UserSubscriber($this->container));
})
->addDefaultListeners()
->addMetadataDir(realpath($this->get('kernel')->getRootDir()."/../") . '/src/Jake/NameOfBundle/Resources/config/serializer')
->build();
return $serializer->serialize($project, 'json');
$project is my entity.
You can omit this line if you don't have serializer configs
->addMetadataDir(realpath($this->get('kernel')->getRootDir()."/../") . '/src/Jake/NameOfBundle/Resources/config/serializer')
I think my main issue was this ->addDefaultListeners().
In config.yml I have
jms_serializer:
metadata:
auto_detection: true
directories:
NameOfBundle:
namespace_prefix: ""
path: "#JakeNameOfBundle/Resources/config/serializer"
I don't have anthing set up to make JMS a service.