Skip to content

Commit

Permalink
Merge branch 'master' into issue-1342-account-name
Browse files Browse the repository at this point in the history
  • Loading branch information
therealmarv committed Jan 13, 2017
2 parents 3264ace + fed3f58 commit 9e54a0a
Show file tree
Hide file tree
Showing 9 changed files with 869 additions and 142 deletions.
223 changes: 223 additions & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,91 @@ If there's an error in the form fields, you will get them in the **form.errors**
"title": "Register"
}
Account sign in
~~~~~~~~~~~~~~~
**Endpoint: /account/signin**

*Allowed methods*: **GET/POST**

**GET**

It returns a JSON object with the following information:

* **auth**: list of supported authentication methods using different social networks like Google, Facebook and Twitter.
* **form**: the form fields that need to be sent for signing a user. It contains the csrf token for validating the post, as well as an errors field in case that something is wrong.
* **template**: The Jinja2 template that could be rendered.

**Example output**

.. code-block:: python
{
"auth": {
"facebook": true,
"google": true,
"twitter": true
},
"form": {
"csrf": "token",
"email": null,
"errors": {},
"password": null
},
"next": null,
"template": "account/signin.html",
"title": "Sign in"
}
**POST**

To send a valid POST request you need to pass the *csrf token* in the headers. Use
the following header: "X-CSRFToken".

It returns a JSON object with the following information:

* **flash**: A success message, or error indicating if the request was succesful.
* **form**: the form fields with the sent information. It contains the csrf token for validating the post, as well as an errors field in case that something is wrong.

**Example output**

.. code-block:: python
{
"auth": {
"facebook": true,
"google": true,
"twitter": true
},
"flash": "Please correct the errors",
"form": {
"csrf": "token",
"email": "prueba@prueba.com",
"errors": {
"password": [
"You must provide a password"
]
},
"password": ""
},
"next": null,
"status": "error",
"template": "account/signin.html",
"title": "Sign in"
}
If the login is successful, then, you will get something like this:

.. code-block:: python
{
"flash": "Welcome back John Doe",
"next": "/",
"status": "success"
}
Account sign out
~~~~~~~~~~~~~~~~
**Endpoint: /account/signout**
Expand Down Expand Up @@ -694,3 +779,141 @@ If there's an error in the form fields, you will get them in the **form.errors**
},
"template": "/account/password_forgot.html"
}
Account update profile
~~~~~~~~~~~~~~~~~~~~~~
**Endpoint: /account/<name>/update**

*Allowed methods*: **GET/POST**

**GET**

It returns a JSON object with the following information:

* **form**: the form fields that need to be sent for updating account. It contains the csrf token for validating the post, as well as an errors field in case that something is wrong.
* **password_form**: the form fields that need to be sent for updating the account's password. It contains the csrf token for validating the post, as well as an errors field in case that something is wrong.
* **upload_form**: the form fields that need to be sent for updating the account's avatar. It contains the csrf token for validating the post, as well as an errors field in case that something is wrong.
* **template**: The Jinja2 template that could be rendered.
* **title**: The title for the view.

**Example output**

.. code-block:: python
{
"flash": null,
"form": {
"ckan_api": null,
"csrf": "token",
"email_addr": "email@emai.com",
"errors": {},
"fullname": "John Doe",
"id": 0,
"locale": "en",
"name": "johndoe",
"privacy_mode": true,
"subscribed": true
},
"password_form": {
"confirm": null,
"csrf": "token",
"current_password": null,
"errors": {},
"new_password": null
},
"show_passwd_form": true,
"template": "/account/update.html",
"title": "Update your profile: John Doe",
"upload_form": {
"avatar": null,
"csrf": "token",
"errors": {},
"id": null,
"x1": 0,
"x2": 0,
"y1": 0,
"y2": 0
}
}
**POST**

To send a valid POST request you need to pass the *csrf token* in the headers. Use
the following header: "X-CSRFToken".

As this endpoint supports **three** different forms, you must specify which form are
you targetting adding an extra key: **btn**. The options for this key are:

* **Profile**: to update the **form**.
**Upload**: to update the **upload_form**.
**Password**: to update the **password_form**.
**External**: to update the **form** but only the external services.

.. note::
Be sure to respect the Uppercase in the first letter, otherwise it will fail.

It returns a JSON object with the following information:

* **flash**: A success message, or error indicating if the request was succesful.
* **form**: the form fields with the sent information. It contains the csrf token for validating the post, as well as an errors field in case that something is wrong.

**Example output**

.. code-block:: python
{
"flash": "Your profile has been updated!",
"next": "/account/pruebaadfadfa/update",
"status": "success"
}
If there's an error in the form fields, you will get them in the **form.errors** key:

.. code-block:: python
{
"flash": "Please correct the errors",
"form": {
"ckan_api": null,
"csrf": "token",
"email_addr": "pruebaprueba.com",
"errors": {
"email_addr": [
"Invalid email address."
]
},
"fullname": "prueba de json",
"id": 0,
"locale": "es",
"name": "pruebaadfadfa",
"privacy_mode": true,
"subscribed": true
},
"password_form": {
"confirm": "",
"csrf": "token",
"current_password": "",
"errors": {},
"new_password": ""
},
"show_passwd_form": true,
"template": "/account/update.html",
"title": "Update your profile: John Doe",
"upload_form": {
"avatar": "",
"csrf": "token",
"errors": {},
"id": 0,
"x1": 0,
"x2": 0,
"y1": 0,
"y2": 0
}
}
.. note::
For updating the avatar is very important to not set the *Content-Type*. If you
are using jQuery, set it to False, so the file is handled properly.

The (x1,x2,y1,y2) are the coordinates for cutting the image and create the avatar.

(x1,y1) are the offset left of the cropped area and the offset top of the cropped
area respectively; and (x2,y2) are the width and height of the crop.
13 changes: 6 additions & 7 deletions pybossa/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
import os
import logging
import humanize
from werkzeug.exceptions import Forbidden, Unauthorized, InternalServerError
from werkzeug.exceptions import NotFound, BadRequest
from flask import Flask, url_for, request, render_template, \
flash, _app_ctx_stack
from flask.ext.login import current_user
Expand All @@ -34,6 +32,7 @@
from pybossa.util import pretty_date, handle_content_type
from pybossa.news import FEED_KEY as NEWS_FEED_KEY
from pybossa.news import get_news
from pybossa.messages import *


def create_app(run_as_server=True):
Expand Down Expand Up @@ -450,31 +449,31 @@ def setup_error_handlers(app):
@app.errorhandler(400)
def _bad_request(e):
response = dict(template='400.html', code=400,
description=BadRequest.description)
description=BADREQUEST)
return handle_content_type(response)

@app.errorhandler(404)
def _page_not_found(e):
response = dict(template='404.html', code=404,
description=NotFound.description)
description=NOTFOUND)
return handle_content_type(response)

@app.errorhandler(500)
def _server_error(e): # pragma: no cover
response = dict(template='500.html', code=500,
description=InternalServerError.description)
description=INTERNALSERVERERROR)
return handle_content_type(response)

@app.errorhandler(403)
def _forbidden(e):
response = dict(template='403.html', code=403,
description=Forbidden.description)
description=FORBIDDEN)
return handle_content_type(response)

@app.errorhandler(401)
def _unauthorized(e):
response = dict(template='401.html', code=401,
description=Unauthorized.description)
description=UNAUTHORIZED)
return handle_content_type(response)


Expand Down
64 changes: 64 additions & 0 deletions pybossa/messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# -*- coding: utf8 -*-
# This file is part of PYBOSSA.
#
# Copyright (C) 2017 Scifabric LTD.
#
# PYBOSSA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PYBOSSA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with PYBOSSA. If not, see <http://www.gnu.org/licenses/>.
"""
PYBOSSA messages.
This module exports the following variables:
* SUCCESS
* ERROR
* WARNING
* FORBIDDEN
* NOTFOUND
* BADREQUEST
* INTERNALSERVERERROR
* NOTFOUND
* UNAUTHORIZED
"""
from werkzeug.exceptions import Forbidden, Unauthorized, InternalServerError
from werkzeug.exceptions import NotFound, BadRequest

__all__ = ['SUCCESS', 'ERROR', 'WARNING', 'FORBIDDEN', 'NOTFOUND', 'BADREQUEST',
'INFO', 'NOTFOUND', 'INTERNALSERVERERROR', 'UNAUTHORIZED']

SUCCESS = "success"

ERROR = "error"

WARNING = "warning"

INFO = "info"

FORBIDDEN = Forbidden.description

NOTFOUND = NotFound.description

BADREQUEST = BadRequest.description

INTERNALSERVERERROR = InternalServerError.description

UNAUTHORIZED = Unauthorized.description

assert SUCCESS
assert ERROR
assert WARNING
assert FORBIDDEN
assert NOTFOUND
assert BADREQUEST
assert INTERNALSERVERERROR
assert UNAUTHORIZED
Loading

0 comments on commit 9e54a0a

Please sign in to comment.