From 92b0761c8fb03f7f012b21448dd393391892e218 Mon Sep 17 00:00:00 2001 From: Kload Date: Sun, 30 Jun 2013 16:13:26 +0000 Subject: [PATCH] RESTful for the win --- action_map.yml | 20 +++++++++---------- yunohost.tac | 52 +++++++++++++++++++++++++++++------------------- yunohost_user.py | 13 ++++++------ 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/action_map.yml b/action_map.yml index 15c86191..2d36f124 100644 --- a/action_map.yml +++ b/action_map.yml @@ -51,7 +51,7 @@ user: ### user_list() list: action_help: List users - api: GET /user/list + api: GET /users arguments: --fields: help: fields to fetch @@ -69,7 +69,7 @@ user: ### user_create() create: action_help: Create user - api: POST /user + api: POST /users arguments: -u: full: --username @@ -95,7 +95,7 @@ user: ### user_delete() delete: action_help: Delete user - api: DELETE /user + api: 'DELETE /users/(?P[^/]+)' arguments: -u: full: --users @@ -109,7 +109,7 @@ user: ### user_update() update: action_help: Update user informations - api: PUT /user + api: 'PUT /users/(?P[^/]+)' arguments: username: help: Username of user to update @@ -143,9 +143,9 @@ user: ### user_info() info: action_help: Get user informations - api: GET /user + api: 'GET /users/(?P[^/]+)' arguments: - user-or-mail: + username: help: Username or mail to get informations @@ -159,7 +159,7 @@ domain: ### domain_list() list: action_help: List domains - api: GET /domain/list + api: GET /domains arguments: -f: full: --filter @@ -174,7 +174,7 @@ domain: ### domain_add() add: action_help: Create a custom domain - api: POST /domain + api: POST /domains arguments: domains: help: Domain name to add @@ -188,7 +188,7 @@ domain: ### domain_remove() remove: action_help: Delete domains - api: DELETE /domain + api: 'DELETE /domains/(?P[^/]+)' arguments: domains: help: Domain(s) to delete @@ -198,7 +198,7 @@ domain: ### domain_info() info: action_help: Get domain informations - api: GET /domain + api: 'GET /domains/(?P[^/]+)' arguments: domain: help: "" diff --git a/yunohost.tac b/yunohost.tac index b4dd0da8..5fca7f2b 100755 --- a/yunohost.tac +++ b/yunohost.tac @@ -21,7 +21,7 @@ gettext.install('YunoHost') action_dict = {} api = APIResource() -def http_exec(request): +def http_exec(request, **kwargs): global win request.setHeader('Access-Control-Allow-Origin', '*') # Allow cross-domain requests @@ -46,45 +46,56 @@ def http_exec(request): request.setHeader('www-authenticate', 'Basic realm="Restricted Area"') return 'Unauthorized' + path = request.path + given_args = request.args + if kwargs: + for k, v in kwargs.iteritems(): + dynamic_key = path.split('/')[-1] + path = path.replace(dynamic_key, '(?P<'+ k +'>[^/]+)') + given_args[k] = [v] + + print given_args # Sanitize arguments - dict = action_dict[request.method+' '+request.path] - if 'arguments' in dict: args = dict['arguments'] - else: args = {} - for arg, params in args.items(): + dict = action_dict[request.method +' '+ path] + if 'arguments' in dict: possible_args = dict['arguments'] + else: possible_args = {} + for arg, params in possible_args.items(): sanitized_key = arg.replace('-', '_') if sanitized_key is not arg: - args[sanitized_key] = args[arg] - del args[arg] + possible_args[sanitized_key] = possible_args[arg] + del possible_args[arg] arg = sanitized_key if arg[0] == '_': if 'nargs' not in params: - args[arg]['nargs'] = '*' + possible_args[arg]['nargs'] = '*' if 'full' in params: new_key = params['full'][2:] else: new_key = arg[2:] - args[new_key] = args[arg] - del args[arg] + possible_args[new_key] = possible_args[arg] + del possible_args[arg] try: # Validate arguments validated_args = {} - for key, value in request.args.items(): - if key in args: + for key, value in given_args.items(): + if key in possible_args: # Validate args - if 'pattern' in args[key]: - validate(args[key]['pattern'], value) - if 'nargs' not in args[key] or ('nargs' != '*' and 'nargs' != '+'): + if 'pattern' in possible_args[key]: + validate(possible_args[key]['pattern'], value) + if 'nargs' not in possible_args[key] or ('nargs' != '*' and 'nargs' != '+'): value = value[0] - if 'choices' in args[key] and value not in args[key]['choices']: + if 'choices' in possible_args[key] and value not in possible_args[key]['choices']: raise YunoHostError(22, _('Invalid argument') + ' ' + value) - if 'action' in args[key] and args[key]['action'] == 'store_true': + if 'action' in possible_args[key] and possible_args[key]['action'] == 'store_true': yes = ['true', 'True', 'yes', 'Yes'] value = value in yes validated_args[key] = value func = str_to_func(dict['function']) + if func is None: + raise YunoHostError(168, _('Function not yet implemented : ') + dict['function'].split('.')[1]) # Execute requested function with YunoHostLDAP(password=request.getPassword()): @@ -106,13 +117,14 @@ def http_exec(request): except YunoHostError, error: # Set response code with function's raised code - server_errors = [1, 111, 169] - client_errors = [13, 17, 22, 87, 122, 125, 167, 168] + server_errors = [1, 111, 168, 169] + client_errors = [13, 17, 22, 87, 122, 125, 167] if error.code in client_errors: request.setResponseCode(400, 'Bad Request') else: request.setResponseCode(500, 'Internal Server Error') - result = { 'error' : error.message } + + result = { 'error' : error.message } return json.dumps(result) diff --git a/yunohost_user.py b/yunohost_user.py index 899abc66..a14e04cc 100644 --- a/yunohost_user.py +++ b/yunohost_user.py @@ -269,13 +269,12 @@ def user_update(username, firstname=None, lastname=None, mail=None, change_passw -def user_info(user_or_mail): +def user_info(username): """ Fetch user informations from LDAP Keyword argument: - username - mail + username -- Username or mail to get info Returns: Dict @@ -283,17 +282,17 @@ def user_info(user_or_mail): with YunoHostLDAP() as yldap: user_attrs = ['cn', 'mail', 'uid', 'maildrop'] - if len(user_or_mail.split('@')) is 2: - filter = 'mail='+ user_or_mail + if len(username.split('@')) is 2: + filter = 'mail='+ username else: - filter = 'uid='+ user_or_mail + filter = 'uid='+ username result = yldap.search('ou=users,dc=yunohost,dc=org', filter, user_attrs) if result: user = result[0] else: - raise YunoHostError(22, _("Unknown user/mail")) + raise YunoHostError(22, _("Unknown user/mail : ") + username) result_dict = { 'Username': user['uid'][0],