diff options
author | Nicolas Lœuillet <nicolas@loeuillet.org> | 2016-03-08 10:09:39 +0100 |
---|---|---|
committer | Nicolas Lœuillet <nicolas@loeuillet.org> | 2016-03-08 10:09:39 +0100 |
commit | 807037884f0085cd39fe4b41cacd82be14e309d9 (patch) | |
tree | a0e01ec2268faa2415e814c38549ae065e32bb7c /src | |
parent | 1e5a4b36ab9e50047e48f247b84733bdf9417844 (diff) | |
parent | d11eb2e461a3ea2b74e5a1c686c9fa9bbcb9e103 (diff) | |
download | wallabag-807037884f0085cd39fe4b41cacd82be14e309d9.tar.gz wallabag-807037884f0085cd39fe4b41cacd82be14e309d9.tar.zst wallabag-807037884f0085cd39fe4b41cacd82be14e309d9.zip |
Merge pull request #1675 from wallabag/v2-create-api-client
Ability to create new client for the API
Diffstat (limited to 'src')
15 files changed, 622 insertions, 0 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/DeveloperController.php b/src/Wallabag/CoreBundle/Controller/DeveloperController.php new file mode 100644 index 00000000..71065534 --- /dev/null +++ b/src/Wallabag/CoreBundle/Controller/DeveloperController.php | |||
@@ -0,0 +1,100 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Controller; | ||
4 | |||
5 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
6 | use Symfony\Component\HttpFoundation\Request; | ||
7 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
8 | use Wallabag\ApiBundle\Entity\Client; | ||
9 | use Wallabag\CoreBundle\Form\Type\ClientType; | ||
10 | |||
11 | class DeveloperController extends Controller | ||
12 | { | ||
13 | /** | ||
14 | * List all clients and link to create a new one. | ||
15 | * | ||
16 | * @Route("/developer", name="developer") | ||
17 | * | ||
18 | * @return \Symfony\Component\HttpFoundation\Response | ||
19 | */ | ||
20 | public function indexAction() | ||
21 | { | ||
22 | $clients = $this->getDoctrine()->getRepository('WallabagApiBundle:Client')->findAll(); | ||
23 | |||
24 | return $this->render('WallabagCoreBundle:Developer:index.html.twig', array( | ||
25 | 'clients' => $clients, | ||
26 | )); | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * Create a client (an app). | ||
31 | * | ||
32 | * @param Request $request | ||
33 | * | ||
34 | * @Route("/developer/client/create", name="developer_create_client") | ||
35 | * | ||
36 | * @return \Symfony\Component\HttpFoundation\Response | ||
37 | */ | ||
38 | public function createClientAction(Request $request) | ||
39 | { | ||
40 | $em = $this->getDoctrine()->getManager(); | ||
41 | $client = new Client(); | ||
42 | $clientForm = $this->createForm(ClientType::class, $client); | ||
43 | $clientForm->handleRequest($request); | ||
44 | |||
45 | if ($clientForm->isValid()) { | ||
46 | $client->setAllowedGrantTypes(array('token', 'authorization_code', 'password')); | ||
47 | $em->persist($client); | ||
48 | $em->flush(); | ||
49 | |||
50 | $this->get('session')->getFlashBag()->add( | ||
51 | 'notice', | ||
52 | 'New client created.' | ||
53 | ); | ||
54 | |||
55 | return $this->render('WallabagCoreBundle:Developer:client_parameters.html.twig', array( | ||
56 | 'client_id' => $client->getPublicId(), | ||
57 | 'client_secret' => $client->getSecret(), | ||
58 | )); | ||
59 | } | ||
60 | |||
61 | return $this->render('WallabagCoreBundle:Developer:client.html.twig', array( | ||
62 | 'form' => $clientForm->createView(), | ||
63 | )); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Remove a client. | ||
68 | * | ||
69 | * @param Client $client | ||
70 | * | ||
71 | * @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client") | ||
72 | * | ||
73 | * @return \Symfony\Component\HttpFoundation\RedirectResponse | ||
74 | */ | ||
75 | public function deleteClientAction(Client $client) | ||
76 | { | ||
77 | $em = $this->getDoctrine()->getManager(); | ||
78 | $em->remove($client); | ||
79 | $em->flush(); | ||
80 | |||
81 | $this->get('session')->getFlashBag()->add( | ||
82 | 'notice', | ||
83 | 'Client deleted' | ||
84 | ); | ||
85 | |||
86 | return $this->redirect($this->generateUrl('developer')); | ||
87 | } | ||
88 | |||
89 | /** | ||
90 | * Display developer how to use an existing app. | ||
91 | * | ||
92 | * @Route("/developer/howto/first-app", name="developer_howto_firstapp") | ||
93 | * | ||
94 | * @return \Symfony\Component\HttpFoundation\Response | ||
95 | */ | ||
96 | public function howtoFirstAppAction() | ||
97 | { | ||
98 | return $this->render('WallabagCoreBundle:Developer:howto_app.html.twig'); | ||
99 | } | ||
100 | } | ||
diff --git a/src/Wallabag/CoreBundle/Form/Type/ClientType.php b/src/Wallabag/CoreBundle/Form/Type/ClientType.php new file mode 100644 index 00000000..dd934715 --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/ClientType.php | |||
@@ -0,0 +1,44 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Form\Type; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\CallbackTransformer; | ||
7 | use Symfony\Component\Form\Extension\Core\Type\SubmitType; | ||
8 | use Symfony\Component\Form\Extension\Core\Type\UrlType; | ||
9 | use Symfony\Component\Form\FormBuilderInterface; | ||
10 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
11 | |||
12 | class ClientType extends AbstractType | ||
13 | { | ||
14 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
15 | { | ||
16 | $builder | ||
17 | ->add('redirect_uris', UrlType::class, array('required' => true, 'label' => 'Redirect URIs')) | ||
18 | ->add('save', SubmitType::class, array('label' => 'Create a new client')) | ||
19 | ; | ||
20 | |||
21 | $builder->get('redirect_uris') | ||
22 | ->addModelTransformer(new CallbackTransformer( | ||
23 | function ($originalUri) { | ||
24 | return $originalUri; | ||
25 | }, | ||
26 | function ($submittedUri) { | ||
27 | return array($submittedUri); | ||
28 | } | ||
29 | )) | ||
30 | ; | ||
31 | } | ||
32 | |||
33 | public function configureOptions(OptionsResolver $resolver) | ||
34 | { | ||
35 | $resolver->setDefaults(array( | ||
36 | 'data_class' => 'Wallabag\ApiBundle\Entity\Client', | ||
37 | )); | ||
38 | } | ||
39 | |||
40 | public function getBlockPrefix() | ||
41 | { | ||
42 | return 'client'; | ||
43 | } | ||
44 | } | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index 6c6caa24..b809f1ab 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml | |||
@@ -242,3 +242,36 @@ If you need some help, we are here for you.: "Parce que vous avez peut-être bes | |||
242 | On GitHub: "Sur GitHub" | 242 | On GitHub: "Sur GitHub" |
243 | By email: "Par email" | 243 | By email: "Par email" |
244 | On Gitter: "Sur Gitter" | 244 | On Gitter: "Sur Gitter" |
245 | |||
246 | # developer | ||
247 | Developer: Développeur | ||
248 | Welcome to the wallabag API: "Bienvenue sur l'API de wallabag" | ||
249 | How to create my first application: "Comment créer votre première application" | ||
250 | View full API documentation: "Voir la documentation complète de l'API" | ||
251 | Clients: "Clients" | ||
252 | Create a new client: "Créer une nouveau client" | ||
253 | Existing clients: "Les clients existants" | ||
254 | Client ID: "ID Client" | ||
255 | Client secret: "Clé secrète" | ||
256 | Redirect URIs: "URLs de redirection" | ||
257 | Grant type allowed: "Type de privilège accordé" | ||
258 | You have the ability to remove this client. This action is IRREVERSIBLE !: "Vous avez la possibilité de supprimer un client. Cette action est IRREVERSIBLE !" | ||
259 | If you remove it, every app configured with that client won't be able to auth on your wallabag.: "Si vous supprimez un client, toutes les applications qui l'utilisaient ne fonctionneront plus avec votre compte wallabag." | ||
260 | Remove this client: "Supprimer ce client" | ||
261 | New client: "Nouveau client" | ||
262 | You are about to create a new client. Please fill the field below for the redirect URI of your application.: "Vous allez créer un nouveau client. Merci de remplir l'url de redirection vers votre application." | ||
263 | Back: "Retour" | ||
264 | Client parameters: "Les paramètres de votre client" | ||
265 | New client created.: "Nouveau client créé." | ||
266 | Here are your client parameters.: "Voilà les paramètres de votre client" | ||
267 | Read the howto "Create my first application": "Lire \"comment créer ma première application\"" | ||
268 | Client deleted: "Client supprimé" | ||
269 | No client yet.: "Aucun client pour le moment" | ||
270 | "The following commands make use of the <a href=\"https://github.com/jkbrzt/httpie\">HTTPie library</a>. Make sure it is installed on your system before using it.": "Les commandes suivantes utilisent la <a href=\"https://github.com/jkbrzt/httpie\">librarie HTTPie</a>. Assurez-vous qu'elle soit installée avant de l'utiliser." | ||
271 | You need a token to communicate between your 3rd application and wallabag API.: "Vous avez besoin d'un token pour échanger entre votre application et l'API de wallabag." | ||
272 | "To create this token, you need <a href=\"%link%\">to create a new client</a>.": "Pour créer un token, vous devez <a href=\"%link%\">créer un nouveau client</a>." | ||
273 | Now, create your token (replace client_id, client_secret, username and password with the good values):: "Maintenant créez votre token (remplacer client_id, client_secret, username et password avec les bonnes valeurs):" | ||
274 | The API will return a response like this:: "L'API vous retournera une réponse comme ça:" | ||
275 | The access_token is useful to do a call to the API endpoint. For example:: "L'access_token doit être utilisé pour faire un appel à l'API. Par exemple :" | ||
276 | This call will return all the entries for your user.: "Cet appel va retourner tous les articles de l'utilisateur." | ||
277 | "If you want to see all the API endpoints, you can have a look <a href=\"%link%\">to our API documentation</a>.": "Si vous voulez toutes les méthodes de l'API, jetez un oeil <a href=\"%link%\">à la documentation de l'API</a>." | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/client.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/client.html.twig new file mode 100644 index 00000000..c9ce6d08 --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/client.html.twig | |||
@@ -0,0 +1,31 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}New client{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | |||
10 | <div class="row"> | ||
11 | <p>{% trans %}You are about to create a new client. Please fill the field below for the redirect URI of your application.{% endtrans %}</p> | ||
12 | {{ form_start(form) }} | ||
13 | {{ form_errors(form) }} | ||
14 | |||
15 | <div class="input-field col s12"> | ||
16 | {{ form_label(form.redirect_uris) }} | ||
17 | {{ form_errors(form.redirect_uris) }} | ||
18 | {{ form_widget(form.redirect_uris) }} | ||
19 | </div> | ||
20 | |||
21 | <a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a> | ||
22 | {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} | ||
23 | |||
24 | {{ form_rest(form) }} | ||
25 | </div> | ||
26 | |||
27 | </div> | ||
28 | </div> | ||
29 | </div> | ||
30 | |||
31 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/client_parameters.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/client_parameters.html.twig new file mode 100644 index 00000000..a214dfd0 --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/client_parameters.html.twig | |||
@@ -0,0 +1,22 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}Client parameters{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | <div class="row"> | ||
10 | <p>{% trans %}Here are your client parameters.{% endtrans %}</p> | ||
11 | <ul> | ||
12 | <li>{% trans %}Client ID{% endtrans %}: <strong><pre>{{ client_id }}</pre></strong></li> | ||
13 | <li>{% trans %}Client secret{% endtrans %}: <strong><pre>{{ client_secret }}</pre></strong></li> | ||
14 | </ul> | ||
15 | |||
16 | <a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a> | ||
17 | <a href="{{ path('developer_howto_firstapp') }}" class="btn waves-effect waves-light">{% trans %}Read the howto "Create my first application"{% endtrans %}</a> | ||
18 | </div> | ||
19 | </div> | ||
20 | </div> | ||
21 | </div> | ||
22 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/howto_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/howto_app.html.twig new file mode 100644 index 00000000..382e6311 --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/howto_app.html.twig | |||
@@ -0,0 +1,63 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}How to create my first application{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block css %} | ||
6 | {{ parent() }} | ||
7 | <link rel="stylesheet" href="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-dark.min.css') }}"> | ||
8 | {% endblock %} | ||
9 | |||
10 | {% block content %} | ||
11 | <div class="row"> | ||
12 | <div class="col s12"> | ||
13 | <div class="card-panel settings"> | ||
14 | |||
15 | <div class="row"> | ||
16 | <p>{% trans %}The following commands make use of the <a href="https://github.com/jkbrzt/httpie">HTTPie library</a>. Make sure it is installed on your system before using it.{% endtrans %}</p> | ||
17 | <p>{% trans %}You need a token to communicate between your 3rd application and wallabag API.{% endtrans %}</p> | ||
18 | <p>{% trans with {'%link%': path('developer_create_client')} %}To create this token, you need <a href="%link%">to create a new client</a>.{% endtrans %}</p> | ||
19 | <p>{% trans %}Now, create your token (replace client_id, client_secret, username and password with the good values):{% endtrans %}</p> | ||
20 | <p> | ||
21 | <pre><code class="language-bash">http POST http://v2.wallabag.org/oauth/v2/token \ | ||
22 | grant_type=password \ | ||
23 | client_id=12_5um6nz50ceg4088c0840wwc0kgg44g00kk84og044ggkscso0k \ | ||
24 | client_secret=3qd12zpeaxes8cwg8c0404g888co4wo8kc4gcw0occww8cgw4k \ | ||
25 | username=yourUsername \ | ||
26 | password=yourPassw0rd</code></pre> | ||
27 | </p> | ||
28 | <p>{% trans %}The API will return a response like this:{% endtrans %}</p> | ||
29 | <p> | ||
30 | <pre><code class="language-bash">HTTP/1.1 200 OK | ||
31 | Cache-Control: no-store, private | ||
32 | Connection: close | ||
33 | Content-Type: application/json | ||
34 | Date: Tue, 06 Oct 2015 18:24:03 GMT | ||
35 | Host: localhost:8000 | ||
36 | Pragma: no-cache | ||
37 | X-Debug-Token: be00a1 | ||
38 | X-Debug-Token-Link: /profiler/be00a1 | ||
39 | X-Powered-By: PHP/5.5.9-1ubuntu4.13 | ||
40 | { | ||
41 | "access_token": "ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw", | ||
42 | "expires_in": 3600, | ||
43 | "refresh_token": "ODBjODU1NWUwNmUzZTBkNDQ5YWVlZTVlMjQ2Y2I0OWM2NTM1ZGM2M2Y3MDhjMTViM2U2MzYxYzRkMDk5ODRlZg", | ||
44 | "scope": null, | ||
45 | "token_type": "bearer" | ||
46 | }</code></pre> | ||
47 | </p> | ||
48 | <p>{% trans %}The access_token is useful to do a call to the API endpoint. For example:{% endtrans %}</p> | ||
49 | <p> | ||
50 | <pre><code class="language-bash">http GET http://v2.wallabag.org/api/entries.json \ | ||
51 | "Authorization:Bearer ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw"</code></pre> | ||
52 | </p> | ||
53 | <p>{% trans %}This call will return all the entries for your user.{% endtrans %}</p> | ||
54 | <p>{% trans with {'%link%': path('nelmio_api_doc_index')} %}If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.{% endtrans %}</p> | ||
55 | <p><a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a></p> | ||
56 | </div> | ||
57 | |||
58 | </div> | ||
59 | </div> | ||
60 | </div> | ||
61 | <script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/prism.min.js') }}"></script> | ||
62 | <script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/components/prism-bash.min.js') }}"></script> | ||
63 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/index.html.twig new file mode 100644 index 00000000..2e7dbcab --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Developer/index.html.twig | |||
@@ -0,0 +1,68 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}Developer{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | |||
10 | <div class="row"> | ||
11 | <h3>{% trans %}Welcome to the wallabag API{% endtrans %}</h3> | ||
12 | |||
13 | <h4>{% trans %}Documentation{% endtrans %}</h4> | ||
14 | |||
15 | <ul> | ||
16 | <li><a href="{{ path('developer_howto_firstapp') }}">{% trans %}How to create my first application{% endtrans %}</a></li> | ||
17 | <li><a href="{{ path('nelmio_api_doc_index') }}">{% trans %}View full API documentation{% endtrans %}</a></li> | ||
18 | </ul> | ||
19 | |||
20 | <h4>{% trans %}Clients{% endtrans %}</h4> | ||
21 | <ul> | ||
22 | <li><a href="{{ path('developer_create_client') }}">{% trans %}Create a new client{% endtrans %}</a></li> | ||
23 | </ul> | ||
24 | |||
25 | <h4>{% trans %}Existing clients{% endtrans %}</h4> | ||
26 | {% if clients %} | ||
27 | <ul class="collapsible" data-collapsible="expandable"> | ||
28 | {% for client in clients %} | ||
29 | <li> | ||
30 | <div class="collapsible-header">#{{ client.id }}</div> | ||
31 | <div class="collapsible-body"> | ||
32 | <table class="striped"> | ||
33 | <tr> | ||
34 | <td>{% trans %}Client ID{% endtrans %}</td> | ||
35 | <td><strong><code>{{ client.id }}_{{ client.randomId }}</code></strong></td> | ||
36 | </tr> | ||
37 | <tr> | ||
38 | <td>{% trans %}Client secret{% endtrans %}</td> | ||
39 | <td><strong><code>{{ client.secret }}</code></strong></td> | ||
40 | </tr> | ||
41 | <tr> | ||
42 | <td>{% trans %}Redirect URIs{% endtrans %}</td> | ||
43 | <td><strong><code>{{ client.redirectUris|json_encode() }}</code></strong></td> | ||
44 | </tr> | ||
45 | <tr> | ||
46 | <td>{% trans %}Grant type allowed{% endtrans %}</td> | ||
47 | <td><strong><code>{{ client.allowedGrantTypes|json_encode() }}</code></strong></td> | ||
48 | </tr> | ||
49 | </table> | ||
50 | <p> | ||
51 | {% trans %}You have the ability to remove this client. This action is IRREVERSIBLE !{% endtrans %}<br/> | ||
52 | {% trans %}If you remove it, every app configured with that client won't be able to auth on your wallabag.{% endtrans %}<br/> | ||
53 | <a class="waves-effect waves-light red btn" href="{{ path('developer_delete_client', {'id': client.id}) }}">{% trans %}Remove this client{% endtrans %}</a> | ||
54 | </p> | ||
55 | </div> | ||
56 | </li> | ||
57 | {% endfor %} | ||
58 | </ul> | ||
59 | {% else %} | ||
60 | {% trans %}No client yet.{% endtrans %} | ||
61 | {% endif %} | ||
62 | </div> | ||
63 | |||
64 | </div> | ||
65 | </div> | ||
66 | </div> | ||
67 | |||
68 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig index 84604762..7f098066 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig | |||
@@ -56,6 +56,7 @@ | |||
56 | {% endif %} | 56 | {% endif %} |
57 | <li><a href="{{ path('import') }}">{% trans %}import{% endtrans %}</a></li> | 57 | <li><a href="{{ path('import') }}">{% trans %}import{% endtrans %}</a></li> |
58 | <li><a href="{{ path('howto') }}">{% trans %}howto{% endtrans %}</a></li> | 58 | <li><a href="{{ path('howto') }}">{% trans %}howto{% endtrans %}</a></li> |
59 | <li><a href="{{ path('developer') }}">{% trans %}Developer{% endtrans %}</a></li> | ||
59 | <li><a href="{{ path('about') }}">{% trans %}about{% endtrans %}</a></li> | 60 | <li><a href="{{ path('about') }}">{% trans %}about{% endtrans %}</a></li> |
60 | <li><a class="icon icon-power" href="{{ path('fos_user_security_logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li> | 61 | <li><a class="icon icon-power" href="{{ path('fos_user_security_logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li> |
61 | </ul> | 62 | </ul> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/client.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/client.html.twig new file mode 100644 index 00000000..c9ce6d08 --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/client.html.twig | |||
@@ -0,0 +1,31 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}New client{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | |||
10 | <div class="row"> | ||
11 | <p>{% trans %}You are about to create a new client. Please fill the field below for the redirect URI of your application.{% endtrans %}</p> | ||
12 | {{ form_start(form) }} | ||
13 | {{ form_errors(form) }} | ||
14 | |||
15 | <div class="input-field col s12"> | ||
16 | {{ form_label(form.redirect_uris) }} | ||
17 | {{ form_errors(form.redirect_uris) }} | ||
18 | {{ form_widget(form.redirect_uris) }} | ||
19 | </div> | ||
20 | |||
21 | <a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a> | ||
22 | {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} | ||
23 | |||
24 | {{ form_rest(form) }} | ||
25 | </div> | ||
26 | |||
27 | </div> | ||
28 | </div> | ||
29 | </div> | ||
30 | |||
31 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/client_parameters.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/client_parameters.html.twig new file mode 100644 index 00000000..a214dfd0 --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/client_parameters.html.twig | |||
@@ -0,0 +1,22 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}Client parameters{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | <div class="row"> | ||
10 | <p>{% trans %}Here are your client parameters.{% endtrans %}</p> | ||
11 | <ul> | ||
12 | <li>{% trans %}Client ID{% endtrans %}: <strong><pre>{{ client_id }}</pre></strong></li> | ||
13 | <li>{% trans %}Client secret{% endtrans %}: <strong><pre>{{ client_secret }}</pre></strong></li> | ||
14 | </ul> | ||
15 | |||
16 | <a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a> | ||
17 | <a href="{{ path('developer_howto_firstapp') }}" class="btn waves-effect waves-light">{% trans %}Read the howto "Create my first application"{% endtrans %}</a> | ||
18 | </div> | ||
19 | </div> | ||
20 | </div> | ||
21 | </div> | ||
22 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/howto_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/howto_app.html.twig new file mode 100644 index 00000000..382e6311 --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/howto_app.html.twig | |||
@@ -0,0 +1,63 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}How to create my first application{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block css %} | ||
6 | {{ parent() }} | ||
7 | <link rel="stylesheet" href="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-dark.min.css') }}"> | ||
8 | {% endblock %} | ||
9 | |||
10 | {% block content %} | ||
11 | <div class="row"> | ||
12 | <div class="col s12"> | ||
13 | <div class="card-panel settings"> | ||
14 | |||
15 | <div class="row"> | ||
16 | <p>{% trans %}The following commands make use of the <a href="https://github.com/jkbrzt/httpie">HTTPie library</a>. Make sure it is installed on your system before using it.{% endtrans %}</p> | ||
17 | <p>{% trans %}You need a token to communicate between your 3rd application and wallabag API.{% endtrans %}</p> | ||
18 | <p>{% trans with {'%link%': path('developer_create_client')} %}To create this token, you need <a href="%link%">to create a new client</a>.{% endtrans %}</p> | ||
19 | <p>{% trans %}Now, create your token (replace client_id, client_secret, username and password with the good values):{% endtrans %}</p> | ||
20 | <p> | ||
21 | <pre><code class="language-bash">http POST http://v2.wallabag.org/oauth/v2/token \ | ||
22 | grant_type=password \ | ||
23 | client_id=12_5um6nz50ceg4088c0840wwc0kgg44g00kk84og044ggkscso0k \ | ||
24 | client_secret=3qd12zpeaxes8cwg8c0404g888co4wo8kc4gcw0occww8cgw4k \ | ||
25 | username=yourUsername \ | ||
26 | password=yourPassw0rd</code></pre> | ||
27 | </p> | ||
28 | <p>{% trans %}The API will return a response like this:{% endtrans %}</p> | ||
29 | <p> | ||
30 | <pre><code class="language-bash">HTTP/1.1 200 OK | ||
31 | Cache-Control: no-store, private | ||
32 | Connection: close | ||
33 | Content-Type: application/json | ||
34 | Date: Tue, 06 Oct 2015 18:24:03 GMT | ||
35 | Host: localhost:8000 | ||
36 | Pragma: no-cache | ||
37 | X-Debug-Token: be00a1 | ||
38 | X-Debug-Token-Link: /profiler/be00a1 | ||
39 | X-Powered-By: PHP/5.5.9-1ubuntu4.13 | ||
40 | { | ||
41 | "access_token": "ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw", | ||
42 | "expires_in": 3600, | ||
43 | "refresh_token": "ODBjODU1NWUwNmUzZTBkNDQ5YWVlZTVlMjQ2Y2I0OWM2NTM1ZGM2M2Y3MDhjMTViM2U2MzYxYzRkMDk5ODRlZg", | ||
44 | "scope": null, | ||
45 | "token_type": "bearer" | ||
46 | }</code></pre> | ||
47 | </p> | ||
48 | <p>{% trans %}The access_token is useful to do a call to the API endpoint. For example:{% endtrans %}</p> | ||
49 | <p> | ||
50 | <pre><code class="language-bash">http GET http://v2.wallabag.org/api/entries.json \ | ||
51 | "Authorization:Bearer ZWFjNjA3ZWMwYWVmYzRkYTBlMmQ3NTllYmVhOGJiZDE0ZTg1NjE4MjczOTVlNzM0ZTRlMWQ0MmRlMmYwNTk5Mw"</code></pre> | ||
52 | </p> | ||
53 | <p>{% trans %}This call will return all the entries for your user.{% endtrans %}</p> | ||
54 | <p>{% trans with {'%link%': path('nelmio_api_doc_index')} %}If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.{% endtrans %}</p> | ||
55 | <p><a href="{{ path('developer') }}" class="waves-effect waves-light grey btn">{% trans %}Back{% endtrans %}</a></p> | ||
56 | </div> | ||
57 | |||
58 | </div> | ||
59 | </div> | ||
60 | </div> | ||
61 | <script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/prism.min.js') }}"></script> | ||
62 | <script src="{{ asset('https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/components/prism-bash.min.js') }}"></script> | ||
63 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/index.html.twig new file mode 100644 index 00000000..2e7dbcab --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Developer/index.html.twig | |||
@@ -0,0 +1,68 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{% trans %}Developer{% endtrans %}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | |||
10 | <div class="row"> | ||
11 | <h3>{% trans %}Welcome to the wallabag API{% endtrans %}</h3> | ||
12 | |||
13 | <h4>{% trans %}Documentation{% endtrans %}</h4> | ||
14 | |||
15 | <ul> | ||
16 | <li><a href="{{ path('developer_howto_firstapp') }}">{% trans %}How to create my first application{% endtrans %}</a></li> | ||
17 | <li><a href="{{ path('nelmio_api_doc_index') }}">{% trans %}View full API documentation{% endtrans %}</a></li> | ||
18 | </ul> | ||
19 | |||
20 | <h4>{% trans %}Clients{% endtrans %}</h4> | ||
21 | <ul> | ||
22 | <li><a href="{{ path('developer_create_client') }}">{% trans %}Create a new client{% endtrans %}</a></li> | ||
23 | </ul> | ||
24 | |||
25 | <h4>{% trans %}Existing clients{% endtrans %}</h4> | ||
26 | {% if clients %} | ||
27 | <ul class="collapsible" data-collapsible="expandable"> | ||
28 | {% for client in clients %} | ||
29 | <li> | ||
30 | <div class="collapsible-header">#{{ client.id }}</div> | ||
31 | <div class="collapsible-body"> | ||
32 | <table class="striped"> | ||
33 | <tr> | ||
34 | <td>{% trans %}Client ID{% endtrans %}</td> | ||
35 | <td><strong><code>{{ client.id }}_{{ client.randomId }}</code></strong></td> | ||
36 | </tr> | ||
37 | <tr> | ||
38 | <td>{% trans %}Client secret{% endtrans %}</td> | ||
39 | <td><strong><code>{{ client.secret }}</code></strong></td> | ||
40 | </tr> | ||
41 | <tr> | ||
42 | <td>{% trans %}Redirect URIs{% endtrans %}</td> | ||
43 | <td><strong><code>{{ client.redirectUris|json_encode() }}</code></strong></td> | ||
44 | </tr> | ||
45 | <tr> | ||
46 | <td>{% trans %}Grant type allowed{% endtrans %}</td> | ||
47 | <td><strong><code>{{ client.allowedGrantTypes|json_encode() }}</code></strong></td> | ||
48 | </tr> | ||
49 | </table> | ||
50 | <p> | ||
51 | {% trans %}You have the ability to remove this client. This action is IRREVERSIBLE !{% endtrans %}<br/> | ||
52 | {% trans %}If you remove it, every app configured with that client won't be able to auth on your wallabag.{% endtrans %}<br/> | ||
53 | <a class="waves-effect waves-light red btn" href="{{ path('developer_delete_client', {'id': client.id}) }}">{% trans %}Remove this client{% endtrans %}</a> | ||
54 | </p> | ||
55 | </div> | ||
56 | </li> | ||
57 | {% endfor %} | ||
58 | </ul> | ||
59 | {% else %} | ||
60 | {% trans %}No client yet.{% endtrans %} | ||
61 | {% endif %} | ||
62 | </div> | ||
63 | |||
64 | </div> | ||
65 | </div> | ||
66 | </div> | ||
67 | |||
68 | {% endblock %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/quickstart.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/quickstart.html.twig index 3d21271a..dea4242b 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/quickstart.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/quickstart.html.twig | |||
@@ -41,6 +41,10 @@ | |||
41 | <li><a href="{{ path('import_wallabag_v1') }}">{% trans %}Migrate from wallabag v1{% endtrans %}</a></li> | 41 | <li><a href="{{ path('import_wallabag_v1') }}">{% trans %}Migrate from wallabag v1{% endtrans %}</a></li> |
42 | <li><a href="{{ path('import_wallabag_v2') }}">{% trans %}Migrate from wallabag v2{% endtrans %}</a></li> | 42 | <li><a href="{{ path('import_wallabag_v2') }}">{% trans %}Migrate from wallabag v2{% endtrans %}</a></li> |
43 | </ul> | 43 | </ul> |
44 | <h4>{% trans %}Developers{% endtrans %}</h4> | ||
45 | <ul> | ||
46 | <li><a href="{{ path('developer') }}">{% trans %}Create your third application{% endtrans %}</a></li> | ||
47 | </ul> | ||
44 | <h4>{% trans %}Full documentation{% endtrans %}</h4> | 48 | <h4>{% trans %}Full documentation{% endtrans %}</h4> |
45 | <ul> | 49 | <ul> |
46 | <li><a href="http://wallabag.readthedocs.org">{% trans %}Annotate your article{% endtrans %}</a></li> | 50 | <li><a href="http://wallabag.readthedocs.org">{% trans %}Annotate your article{% endtrans %}</a></li> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig index d7bfa7ae..f5d03084 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig | |||
@@ -50,6 +50,7 @@ | |||
50 | {% endif %} | 50 | {% endif %} |
51 | <li class="bold {% if currentRoute == 'import' %}active{% endif %}"><a class="waves-effect" href="{{ path('import') }}">{% trans %}import{% endtrans %}</a></li> | 51 | <li class="bold {% if currentRoute == 'import' %}active{% endif %}"><a class="waves-effect" href="{{ path('import') }}">{% trans %}import{% endtrans %}</a></li> |
52 | <li class="bold {% if currentRoute == 'howto' %}active{% endif %}"><a class="waves-effect" href="{{ path('howto') }}">{% trans %}howto{% endtrans %}</a></li> | 52 | <li class="bold {% if currentRoute == 'howto' %}active{% endif %}"><a class="waves-effect" href="{{ path('howto') }}">{% trans %}howto{% endtrans %}</a></li> |
53 | <li class="bold {% if currentRoute == 'developer' %}active{% endif %}"><a class="waves-effect" href="{{ path('developer') }}">{% trans %}Developer{% endtrans %}</a></li> | ||
53 | <li class="bold"><a class="waves-effect" class="icon icon-power" href="{{ path('fos_user_security_logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li> | 54 | <li class="bold"><a class="waves-effect" class="icon icon-power" href="{{ path('fos_user_security_logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li> |
54 | </ul> | 55 | </ul> |
55 | <div class="nav-wrapper nav-panels"> | 56 | <div class="nav-wrapper nav-panels"> |
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php new file mode 100644 index 00000000..fc220b85 --- /dev/null +++ b/src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php | |||
@@ -0,0 +1,71 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Tests\Controller; | ||
4 | |||
5 | use Wallabag\CoreBundle\Tests\WallabagCoreTestCase; | ||
6 | |||
7 | class DeveloperControllerTest extends WallabagCoreTestCase | ||
8 | { | ||
9 | public function testCreateClient() | ||
10 | { | ||
11 | $this->logInAs('admin'); | ||
12 | $client = $this->getClient(); | ||
13 | $em = $client->getContainer()->get('doctrine.orm.entity_manager'); | ||
14 | $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); | ||
15 | |||
16 | $crawler = $client->request('GET', '/developer/client/create'); | ||
17 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
18 | |||
19 | $form = $crawler->filter('button[type=submit]')->form(); | ||
20 | |||
21 | $client->submit($form); | ||
22 | |||
23 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
24 | |||
25 | $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); | ||
26 | $this->assertGreaterThan(count($nbClients), count($newNbClients)); | ||
27 | } | ||
28 | |||
29 | public function testListingClient() | ||
30 | { | ||
31 | $this->logInAs('admin'); | ||
32 | $client = $this->getClient(); | ||
33 | $em = $client->getContainer()->get('doctrine.orm.entity_manager'); | ||
34 | $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); | ||
35 | |||
36 | $crawler = $client->request('GET', '/developer'); | ||
37 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
38 | $this->assertEquals(count($nbClients), $crawler->filter('ul[class=collapsible] li')->count()); | ||
39 | } | ||
40 | |||
41 | public function testDeveloperHowto() | ||
42 | { | ||
43 | $this->logInAs('admin'); | ||
44 | $client = $this->getClient(); | ||
45 | |||
46 | $crawler = $client->request('GET', '/developer/howto/first-app'); | ||
47 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
48 | } | ||
49 | |||
50 | public function testRemoveClient() | ||
51 | { | ||
52 | $this->logInAs('admin'); | ||
53 | $client = $this->getClient(); | ||
54 | $em = $client->getContainer()->get('doctrine.orm.entity_manager'); | ||
55 | $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); | ||
56 | |||
57 | $crawler = $client->request('GET', '/developer'); | ||
58 | |||
59 | $link = $crawler | ||
60 | ->filter('div[class=collapsible-body] p a') | ||
61 | ->eq(0) | ||
62 | ->link() | ||
63 | ; | ||
64 | |||
65 | $client->click($link); | ||
66 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
67 | |||
68 | $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); | ||
69 | $this->assertGreaterThan(count($newNbClients), count($nbClients)); | ||
70 | } | ||
71 | } | ||