Commit fa639d77 authored by hlarget's avatar hlarget 👹
Browse files

Refactorisation

Merge branch 'release/2.0.4'
parents 851234b9 ea7021eb
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="4b37c6c9-9d1a-4296-8847-77d4ae82e85d" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Controller/CompanyController.php" beforeDir="false" afterPath="$PROJECT_DIR$/Controller/CompanyController.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Controller/ServiceController.php" beforeDir="false" afterPath="$PROJECT_DIR$/Controller/ServiceController.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Controller/UserController.php" beforeDir="false" afterPath="$PROJECT_DIR$/Controller/UserController.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/KonnectClient.php" beforeDir="false" afterPath="$PROJECT_DIR$/KonnectClient.php" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ComposerSettings" doNotAsk="true" synchronizationState="SYNCHRONIZE">
<pharConfigPath>$PROJECT_DIR$/composer.json</pharConfigPath>
<execution>
<executable path="composer" />
</execution>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IgnoredFileRootStore">
<option name="generatedRoots">
<set>
<option value="$PROJECT_DIR$/.idea" />
</set>
</option>
</component>
<component name="ProjectId" id="1PolypSKvnr70tdTHfjGxNBeFx3" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.tslint" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="settings.editor.selected.configurable" value="preferences.pluginManager" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
</key>
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="ServiceViewManager">
<option name="allServicesViewState">
<serviceView>
<treeState>
<expand />
<select />
</treeState>
</serviceView>
</option>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="4b37c6c9-9d1a-4296-8847-77d4ae82e85d" name="Default Changelist" comment="" />
<created>1566548586636</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1566548586636</updated>
<workItem from="1566548587759" duration="4239000" />
<workItem from="1566802400827" duration="14289000" />
<workItem from="1568618425023" duration="4384000" />
<workItem from="1568723670930" duration="25348000" />
<workItem from="1569490108301" duration="1436000" />
<workItem from="1570083917085" duration="19150000" />
<workItem from="1570292215018" duration="15675000" />
<workItem from="1570460540839" duration="7282000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="COLUMN_ORDER" />
</State>
</value>
</entry>
</map>
</option>
</component>
</project>
\ No newline at end of file
......@@ -4,6 +4,8 @@ namespace Aboutgoods\KonnectBundle\Controller;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use Aboutgoods\KonnectBundle\KonnectClient;
use Aboutgoods\KonnectBundle\Services\KonnectApi;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
......@@ -12,36 +14,28 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class CompanyController extends Controller
class CompanyController extends AbstractController
{
/**
* Send a request to Kweeri Konnect to reset the company hydra token
* @Route("/company/reset_secret")
* @return
*
* @param KonnectClient $konnectClient
*
* @return Response
*/
public function resetCompanySecret()
public function resetCompanySecret(KonnectClient $konnectClient)
{
if (!in_array("OWNER", $this->getUser()->getRoles())) {
return new Response("Only owner is allowed to reset the secret", Response::HTTP_FORBIDDEN);
}
$api = $this->get("konnect.api");
$companyId = $this->getUser()->getCompanyId();
$config = $this->get('konnect.client')->getConfiguration();
$newSecret = $api->resetCompanySecret($companyId, $config);
return $this->json(["client_secret" => $newSecret["client_secret"]]);
}
/**
* Returns the user's company id
* @Route("/company/id")
* @return
*/
public function getCompanyId()
{
$client = $konnectClient->getGuzzleClient();
$companyId = $this->getUser()->getCompanyId();
return $this->json(["companyId" => $companyId]);
$response = $client->get("/api/company/$companyId/reset_secret");
return new Response($response->getBody()->getContents(), Response::HTTP_OK, ['Content-Type' => 'application/json']);
}
}
\ No newline at end of file
......@@ -13,10 +13,12 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class MainController extends Controller
class MainController extends AbstractController
{
/**
* Return the user in format JSON (mostly used by the Front end)
* @return mixed
* @Route("/whoAmI")
*/
......
......@@ -3,20 +3,29 @@
namespace Aboutgoods\KonnectBundle\Controller;
use GuzzleHttp\Client;
use Aboutgoods\KonnectBundle\KonnectClient;
use Symfony\Component\HttpFoundation\Response;
use Aboutgoods\KonnectBundle\Services\KonnectApi;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ServiceController extends Controller
class ServiceController extends AbstractController
{
/**
* @Route("/services/menu", name="services.menu")
*
* @return
*/
public function getServicesListForMenu()
* Get a list of all the services that exists to create the menu
* @Route("/services/menu", name="services.menu")
*
* @param KonnectClient $konnectClient
*
* @return Response
*/
public function getServicesListForMenu(KonnectClient $konnectClient)
{
$api = $this->get("konnect.api");
$config = $this->get('konnect.client')->getConfiguration();
return $this->json($api->getServicesListForMenu($config));
$client = $konnectClient->getGuzzleClient();
$response = $client->get("/api/services/menu");
return new Response($response->getBody()->getContents(), Response::HTTP_OK, ['Content-Type' => 'application/json']);
}
}
\ No newline at end of file
......@@ -2,8 +2,8 @@
namespace Aboutgoods\KonnectBundle\Controller;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use Aboutgoods\KonnectBundle\KonnectClient;
use Aboutgoods\KonnectBundle\Services\KonnectApi;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
......@@ -12,6 +12,8 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use GuzzleHttp\Client;
/**
* Created by PhpStorm.
......@@ -20,10 +22,11 @@ use Symfony\Component\Routing\Annotation\Route;
* Time: 09:31
*/
class LoginController extends Controller
class UserController extends AbstractController
{
/**
* @Route("/logout", name="konnect.logout")
* This route is a shortcut to call the route auth0_logout of the HWIOauth Bundle
* @return RedirectResponse
*/
public function logout()
......@@ -33,14 +36,18 @@ class LoginController extends Controller
/**
* @Route("/user/services")
* List all user services from the current connected user.
*
* @return
* @param KonnectClient $konnectClient
*
* @return Response
*/
public function getUserServices()
public function getUserServices(KonnectClient $konnectClient)
{
$api = $this->get("konnect.api");
$client = $konnectClient->getGuzzleClient();
$userId = $this->getUser()->getId();
$config = $this->get('konnect.client')->getConfiguration();
return $this->json($api->getUserServices($userId, $config));
$response = $client->get("/api/user/$userId/services");
return new Response($response->getBody()->getContents(), Response::HTTP_OK, ['Content-Type' => 'application/json']);
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files.
*
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
*/
class Configuration implements ConfigurationInterface
......
......@@ -9,7 +9,6 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class KonnectExtension extends Extension
......
......@@ -7,6 +7,8 @@
*/
namespace Aboutgoods\KonnectBundle;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use Aboutgoods\KonnectBundle\Event\LoginEvent;
use Aboutgoods\KonnectBundle\Event\LogoutEvent;
use net\aboutgoods\konnect\Konnect;
......@@ -14,15 +16,24 @@ use net\aboutgoods\konnect\model\response\Authorization;
use net\aboutgoods\konnect\model\response\User;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class Client
/**
* Class KonnectClient
* @package Aboutgoods\KonnectBundle
* This class allow symfony to get the config from the `konnect.yml`
*/
class KonnectClient
{
protected $configuration;
public function getConfiguration()
{
return $this->configuration;
}
/**
* This method is called in the KonnectExtension.php
* @param $config
*/
public function setConfiguration($config)
{
$this->configuration = [
......@@ -32,6 +43,7 @@ class Client
"url" => null
],
];
// Recursive replace with the config passed as parameter
foreach ($this->configuration as $key => $value) {
if(is_array($value)) {
foreach ($value as $subKey => $subValue) {
......@@ -46,4 +58,13 @@ class Client
}
}
}
public function getGuzzleClient()
{
$config = $this->getConfiguration()['authentication'];
return new Client([
"base_uri" => $config['url'],
"auth" => [$config['token'], $config['secret']]
]);
}
}
\ No newline at end of file
services:
konnect.client:
class: Aboutgoods\KonnectBundle\Client
class: Aboutgoods\KonnectBundle\KonnectClient
public: true
Aboutgoods\KonnectBundle\Client:
Aboutgoods\KonnectBundle\KonnectClient:
alias: konnect.client
##
# CONTROLLER
##
konnect.login.controller:
class: Aboutgoods\KonnectBundle\Controller\LoginController
class: Aboutgoods\KonnectBundle\Controller\UserController
public: true
Aboutgoods\KonnectBundle\Controller\LoginController:
Aboutgoods\KonnectBundle\Controller\UserController:
alias: konnect.login.controller
konnect.company.controller:
......@@ -31,9 +31,3 @@ services:
class: Aboutgoods\KonnectBundle\Security\Provider\UserProvider
Aboutgoods\KonnectBundle\Security\Provider\UserProvider:
alias: konnect.user.provider
konnect.api:
class: Aboutgoods\KonnectBundle\Services\KonnectApi
public: true
Aboutgoods\KonnectBundle\Services\KonnectApi:
alias: konnect.api
......@@ -8,6 +8,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericOAuth2ResourceOwner;
//Todo: Maybe put this into a specific library
class Auth0ResourceOwner extends GenericOAuth2ResourceOwner
{
......
......@@ -10,6 +10,7 @@ use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface;
use function Couchbase\defaultDecoder;
//Todo: Maybe put this into a specific library
class UserProvider implements UserProviderInterface, OAuthAwareUserProviderInterface
{
const AUTH0_USER_DATA_KEY_PICTURE = 'picture';
......
<?php
namespace Aboutgoods\KonnectBundle\Services;
use GuzzleHttp\Client;
class KonnectApi
{
public function getUserServices($userId, $config) {
$client = new Client();
$config = $config['authentication'];
$response = $client->get($config['url'] . "/api/user/$userId/services", [
'auth' => [
$config['token'],
$config['secret']
]
]);
return json_decode($response->getBody()->getContents(),true);
}
public function resetCompanySecret($companyId, $config) {
$client = new Client();
$config = $config['authentication'];
$response = $client->get($config['url'] . "/api/company/$companyId/reset_secret", [
'auth' => [
$config['token'],
$config['secret']
]
]);
return json_decode($response->getBody()->getContents(),true);
}
public function getServicesListForMenu($config) {
$client = new Client();
$config = $config['authentication'];
$response = $client->get($config['url'] . "/api/services/menu", [
'auth' => [
$config['token'],
$config['secret']
]
]);
return json_decode($response->getBody()->getContents(),true);
}
}
\ No newline at end of file
Konnect Bundle
====================
This project aims to mutualize the code used by konnect and its modules.
Konnect Bundle have two main goals:
- Give a way to project to authenticate
- Allow Modules to call Konnect API
- Give a way to project to authenticate to Auth0
- All the common Auth0 files are stored here to avoid duplicate in all project
- Allow Modules to call Konnect API to get informations about user or about service.
Take a look at [the Konnect Bundle API documentation](https://doc.agoods.fr/v2/api/konnectBundle.html)
Konnect Bundle import some classes in your module:
- Auth0ResourceOwner that make call to Auth0 for the Authentication
- User entity to have a common User across all our modules
- User Provider to populate the User Entity with Auth0 response
## Installation
You need to install this package with composer using the following command:
......@@ -27,10 +35,11 @@ Aboutgoods\KonnectBundle\KonnectBundle::class => ['all' => true],
in `/config/bundles.php`
Configuration
=======================
##Configuration
If you need to make call to the API of Konnect you need to configure Konnect-bundle
In your `konnect.yml`:
```yaml
# Default configuration for "KonnectBundle"
konnect:
......@@ -38,4 +47,73 @@ konnect:
token: '%env(KONNECT_TOKEN)%' #token of your services on konnect
secret: '%env(KONNECT_SECRET)%' #secret of your services on konnect
url: '%env(KONNECT_URI)%'
```
\ No newline at end of file
```
In your `.env`:
```dotenv
KONNECT_TOKEN=YOUR_SERVICE_TOKEN
KONNECT_SECRET=YOUR_SERVICE_SECRET
KONNECT_URI=127.0.0.1:10080
```
For the basic services you can find their `TOKEN` and `SECRET` [on the Konnect readme](https://gitlab.agoods.fr/presentation/kweeri/Kweeri-Konnect/blob/dev/README.md#token-and-secret-for-each-services-).
##Usage
Once this library is installed and configured you need to import all the routes of this bundle:
In your `annotations.yaml` you need to add :
```yaml
konnect-bundle:
resource: "@KonnectBundle/Controller/"
type: annotation
prefix: /konnect
```
After that all the routes are imported you need to use the user provider in your `security.yml`:
```yaml
security:
providers:
hwi:
id: Aboutgoods\KonnectBundle\Security\Provider\UserProvider
firewalls:
main:
provider: hwi
anonymous: ~
oauth:
resource_owners:
auth0: "/auth0/callback"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: Aboutgoods\KonnectBundle\Security\Provider\UserProvider
logout:
path: /auth0/logout
target: /
success_handler: App\Listener\LogoutListener
```
After this you should connect to your application and call the routes in this bundle to call Konnect.
You can find RAML documentation [on dev-documentation.](https://doc.agoods.fr/v2/api/konnectBundle.html).
##Use this library in an empty Symfony project
You can find [a detailed documentation here](https://gitlab.agoods.fr/documentation/dev-documentation/blob/master/Support/Konnect/HowToCreateAKonnectModule.md).
##Development FAQ
##### You need to add a route to Konnect-Bundle ?
- Set a route on a Controller
> If you add a new controller, you need to declare this controller in `Resources/config/services.yml` with the same syntax that existent controllers
> *NOTE*: don't use autowiring on Konnect Bundle, use `$api = $this->get("konnect.api");` for example where `konnect.api` is the alias for KonnectApi set in `services.yml`
- Add a function in the `Services/KonnectApi.php` that calls a route on Konnect. You need to pass a config array with token/secret to authenticate the service on Konnect. See existent functions to know how to do that.
##### You need to add a file to use it on modules ?
- Put your files on a folder
- Use it on the module by specifying the Konnect-Bundle namespace
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment