api: add API to get list of users (#8345)

This commit is contained in:
Frédéric Péters 2015-09-24 10:47:51 +02:00
parent 17d6ad423e
commit 5843ad8f33
3 changed files with 77 additions and 9 deletions

View File

@ -15,22 +15,18 @@
<title>Récupération des données d'un utilisateur</title>
<p>
Il s'agit ici d'une API permettant à un logiciel tiers de récupérer les données
associées à un utilisateur; cet accès peut aussi bien être initié par
l'application tierce (mode pull) ou par w.c.s., à différents moments (création
de l'utilisateur, modification, etc.).
Il s'agit ici d'API permettant à un logiciel tiers de récupérer les données
associées aux utilisateurs enregistrés.
</p>
<section id="pull">
<title>Mode pull</title>
<section>
<title>Profil</title>
<p>
Ces accès doivent se faire en passant les informations d'identification
appropriées dans la <em>query string</em>.
</p>
<section>
<title>Profil</title>
<p>
Les informations associées à un utilisateur sont accessibles à l'URL
<code>/api/user/</code>, elles reprennent son nom (<code>user_display_name</code>),
@ -166,6 +162,35 @@ l'adresse <code>/myspace/drafts</code>.
</section>
<section>
<title>Liste des utilisateurs</title>
<p>
La liste des utilisateurs est disponible à l'URL <code>/api/users/</code>,
il est possible de la filtrer, sur le nom ou l'adresse électronique, en
spécifiant un paramètre <code>q</code> et de limiter le nombre de
résultats obtenus avec le paramètre <code>limit</code>.
</p>
<screen>
<output style="prompt">$ </output><input>curl -H "Accept: application/json" \
https://www.example.net/api/users/?q=fred</input>
<output>
{
"err": 0,
"data": [
{
"user_display_name": "Fred",
"user_email": "fred@example.net",
"user_backoffice_access": true,
"user_admin_access": false
}
}
}
</output>
</screen>
</section>
</page>

View File

@ -542,3 +542,17 @@ def test_roles(local_user):
assert resp.json['data'][0]['emails'] == ['toto@example.com', 'zozo@example.com']
assert resp.json['data'][0]['emails_to_members'] == False
assert resp.json['data'][0]['details'] == 'kouign amann'
def test_users(local_user):
resp = get_app(pub).get('/api/users/', status=403)
resp = get_app(pub).get(sign_uri('/api/users/'))
assert resp.json['data'][0]['user_display_name'] == local_user.name
assert resp.json['data'][0]['user_email'] == local_user.email
assert resp.json['data'][0]['user_id'] == local_user.id
resp = get_app(pub).get(sign_uri('/api/users/?q=jean'))
assert resp.json['data'][0]['user_email'] == local_user.email
resp = get_app(pub).get(sign_uri('/api/users/?q=foobar'))
assert len(resp.json['data']) == 0

View File

@ -36,6 +36,7 @@ from wcs.categories import Category
from wcs.formdef import FormDef
from wcs.roles import Role, logged_users_role
from wcs.forms.root import RootDirectory
import wcs.qommon.storage as st
def is_url_signed():
@ -435,14 +436,42 @@ class ApiUserDirectory(Directory):
encoding=get_publisher().site_charset)
class ApiUsersDirectory(Directory):
_q_exports = ['']
def _q_index(self):
get_response().set_content_type('application/json')
if not (is_url_signed() or (
get_request().user and get_request().user.can_go_in_admin())):
raise AccessForbiddenError()
criterias = []
query = get_request().form.get('q')
if query:
criterias.append(st.Or([st.ILike('name', query), st.ILike('email', query)]))
def as_dict(user):
user_info = user.get_substitution_variables(prefix='')
del user_info['user']
user_info['user_id'] = user.id
return user_info
limit = int(get_request().form.get('limit') or '0') or None
users = get_publisher().user_class.select(order_by='name',
clause=criterias, limit=limit)
data = [as_dict(x) for x in users]
return json.dumps({'data': data, 'err': 0})
class ApiDirectory(Directory):
_q_exports = ['forms', 'roles', ('reverse-geocoding', 'reverse_geocoding'),
'formdefs', 'categories', 'user']
'formdefs', 'categories', 'user', 'users']
forms = ApiFormsDirectory()
formdefs = ApiFormdefsDirectory()
categories = ApiCategoriesDirectory()
user = ApiUserDirectory()
users = ApiUsersDirectory()
def reverse_geocoding(self):
try: