GraphQL - Add viewer query

Refs #2644
pull/2650/head^2
Angel Fernando Quiroz Campos 6 years ago
parent a3d52579f3
commit 5ffaf25e9e
  1. 40
      src/ApiBundle/GraphQL/Auth.php
  2. 24
      src/ApiBundle/GraphQL/Resolver/RootResolver.php
  3. 59
      src/ApiBundle/GraphQL/Resolver/UserResolver.php
  4. 35
      src/ApiBundle/GraphQL/Type/Enum.types.yaml
  5. 31
      src/ApiBundle/GraphQL/Type/Query.types.yaml

@ -6,7 +6,6 @@ namespace Chamilo\ApiBundle\GraphQL;
use Chamilo\CoreBundle\Framework\Container; use Chamilo\CoreBundle\Framework\Container;
use Chamilo\UserBundle\Entity\User; use Chamilo\UserBundle\Entity\User;
use Firebase\JWT\JWT; use Firebase\JWT\JWT;
use Overblog\GraphQLBundle\Error\UserError;
/** /**
* Class Auth * Class Auth
@ -21,16 +20,15 @@ class Auth
* @param string $password * @param string $password
* *
* @return string * @return string
* @throws \Exception
*/ */
public function getUserToken($username, $password): string public function getUserToken($username, $password): string
{ {
$userRepo = Container::getEntityManager()->getRepository('ChamiloUserBundle:User');
/** @var User $user */ /** @var User $user */
$user = $userRepo->findOneByUsername($username); $user = Container::getUserManager()->findUserBy(['username' => $username]);
if (!$user) { if (!$user) {
throw new UserError(get_lang('NoUser')); throw new \Exception(get_lang('NoUser'));
} }
$encoder = Container::$container->get('chamilo_user.security.encoder'); $encoder = Container::$container->get('chamilo_user.security.encoder');
@ -41,7 +39,7 @@ class Auth
); );
if (!$isValid) { if (!$isValid) {
throw new UserError(get_lang('InvalidId')); throw new \Exception(get_lang('InvalidId'));
} }
return self::generateToken($user->getId()); return self::generateToken($user->getId());
@ -52,7 +50,7 @@ class Auth
* *
* @return string * @return string
*/ */
public static function generateToken($userId): string private static function generateToken($userId): string
{ {
$secret = Container::$container->getParameter('secret'); $secret = Container::$container->getParameter('secret');
$time = time(); $time = time();
@ -68,12 +66,38 @@ class Auth
return JWT::encode($payload, $secret, 'HS384'); return JWT::encode($payload, $secret, 'HS384');
} }
/**
* @param \ArrayObject $context
*
* @throws \Exception
*/
public static function checkAuthorization(\ArrayObject $context): void
{
$header = Container::getRequest()->headers->get('Authorization');
$token = str_replace(['Bearer ', 'bearer '], '', $header);
if (empty($token)) {
throw new \Exception(get_lang('NotAllowed'));
}
$tokenData = Auth::getTokenData($token);
/** @var User $user */
$user = Container::getUserManager()->find($tokenData['user']);
if (!$user) {
throw new \Exception(get_lang('NotAllowed'));
}
$context->offsetSet('user', $user);
}
/** /**
* @param string $token * @param string $token
* *
* @return array * @return array
*/ */
public static function getTokenData($token): array private static function getTokenData($token): array
{ {
$secret = Container::$container->getParameter('secret'); $secret = Container::$container->getParameter('secret');
$jwt = JWT::decode($token, $secret, ['HS384']); $jwt = JWT::decode($token, $secret, ['HS384']);

@ -3,9 +3,11 @@
namespace Chamilo\ApiBundle\GraphQL\Resolver; namespace Chamilo\ApiBundle\GraphQL\Resolver;
use Chamilo\CoreBundle\Framework\Container; use Chamilo\ApiBundle\GraphQL\Auth;
use Chamilo\UserBundle\Entity\User;
use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface; use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface; use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
use Overblog\GraphQLBundle\Error\UserError;
/** /**
* Class RootResolver * Class RootResolver
@ -26,6 +28,26 @@ class RootResolver implements ResolverInterface, AliasedInterface
public static function getAliases() public static function getAliases()
{ {
return [ return [
'resolverViewer' => 'viewer',
]; ];
} }
/**
* @param \ArrayObject $context
*
* @return User
*/
public function resolverViewer(\ArrayObject $context)
{
try {
Auth::checkAuthorization($context);
} catch (\Exception $exception) {
throw new UserError($exception->getMessage());
}
/** @var User $user */
$user = $context->offsetGet('user');
return $user;
}
} }

@ -0,0 +1,59 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\ApiBundle\GraphQL\Resolver;
use Chamilo\CoreBundle\Framework\Container;
use Chamilo\UserBundle\Entity\User;
use Overblog\GraphQLBundle\Definition\Argument;
use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
/**
* Class UserResolver
*
* @package Chamilo\ApiBundle\GraphQL\Resolver
*/
class UserResolver implements ResolverInterface, AliasedInterface
{
public const IMAGE_SIZE_TINY = 16;
public const IMAGE_SIZE_SMALL = 32;
public const IMAGE_SIZE_MEDIUM = 64;
public const IMAGE_SIZE_BIG = 128;
/**
* Returns methods aliases.
*
* For instance:
* array('myMethod' => 'myAlias')
*
* @return array
*/
public static function getAliases(): array
{
return [
'resolveUserPicture' => 'user_picture',
];
}
/**
* @param int $size
* @param \ArrayObject $context
*
* @return string
*/
public function resolveUserPicture($size, \ArrayObject $context): string
{
/** @var User $user */
$user = $context->offsetGet('user');
if (!$user) {
return null;
}
$path = $user->getAvatarOrAnonymous((int) $size);
$url = Container::getAsset()->getUrl($path);
return $url;
}
}

@ -0,0 +1,35 @@
UserStatus:
type: enum
config:
description: "One of the statuses for the user."
values:
TEACHER:
description: "Global status of a user: Course Manager."
value: '@=constant("Chamilo\\UserBundle\\Entity\\User::TEACHER")'
SESSION_ADMIN:
description: "Global status of a user: Session Admin."
value: '@=constant("Chamilo\\UserBundle\\Entity\\User::SESSION_ADMIN")'
DRH:
description: "Global status of a user: Human Ressource Manager."
value: '@=constant("Chamilo\\UserBundle\\Entity\\User::DRH")'
STUDENT:
description: "Global status of a user: Student."
value: '@=constant("Chamilo\\UserBundle\\Entity\\User::STUDENT")'
UserImageSize:
type: enum
config:
description: 'One of the sizes for the user picture.'
values:
SIZE_TINY:
description: 'Image in small size: 16px.'
value: '@=constant("Chamilo\\ApiBundle\\GraphQL\\Resolver\\UserResolver::IMAGE_SIZE_TINY")'
SIZE_SMALL:
description: 'Image in small size: 32px.'
value: '@=constant("Chamilo\\ApiBundle\\GraphQL\\Resolver\\UserResolver::IMAGE_SIZE_SMALL")'
SIZE_MEDIUM:
description: 'Image in small size: 64px.'
value: '@=constant("Chamilo\\ApiBundle\\GraphQL\\Resolver\\UserResolver::IMAGE_SIZE_MEDIUM")'
SIZE_BIG:
description: 'Image in small size: 128px.'
value: '@=constant("Chamilo\\ApiBundle\\GraphQL\\Resolver\\UserResolver::IMAGE_SIZE_BIG")'

@ -3,6 +3,35 @@ Query:
config: config:
description: "GraphQL queries." description: "GraphQL queries."
fields: fields:
user: viewer:
description: "A registered user on the platform." description: "A registered user on the platform."
type: "User"
resolve: "@=resolver('viewer', [context])"
User:
type: object
config:
description: "Registered user."
fields:
id:
description: "The unique ID of the user."
type: "Int"
firstname:
type: "String"
lastname:
type: "String"
username:
type: "String"
email:
type: "String"
officialCode:
type: "String"
status:
type: "UserStatus"
picture:
type: "String" type: "String"
args:
size:
type: "UserImageSize"
defaultValue: '@=constant("Chamilo\\ApiBundle\\GraphQL\\Resolver\\UserResolver::IMAGE_SIZE_SMALL")'
resolve: "@=resolver('user_picture', [args['size'], context])"

Loading…
Cancel
Save