Ejemplo n.º 1
0
    def put(self, id_):
        '''
        Update data about the application identified by `id`. Omitted fields
        are not changed.

        **Example Request**

        .. sourcecode:: json

            {
                "agency": "Department Of Justice",
                "email": "*****@*****.**",
                "is_admin": true,
                "location": "Washington, DC",
                "name": "Lt. John Doe",
                "password": "******",
                "phone": "+12025551234",
                "credits": 10,
                "thumb": "iVBORw0KGgoAAAANS..."
            }

        **Example Response**

        .. sourcecode:: json

            {
                "agency": "Department Of Justice",
                "created": "2015-05-05T14:30:09.676268",
                "email": "*****@*****.**",
                "id": 2029,
                "is_admin": true,
                "location": "Washington, DC",
                "modified": "2015-05-05T14:30:09.676294",
                "name": "Lt. John Doe",
                "phone": "202-555-1234",
                "thumb": "iVBORw0KGgoAAAANS...",
                "credits": 10,
                "url": "https://quickpin/api/user/2029"
            }

        :<header Content-Type: application/json
        :<header X-Auth: the client's auth token
        :<json str agency: the name of the organization/agency that this person
           is affiliated with
        :<json str email: e-mail address
        :<json bool is_admin: true if this user should have admin privileges,
           false otherwise (this field can only be modified by an admin user)
        :<json str location: location name, e.g. city or state (default: null)
        :<json str name: user's full name, optionally including title or other
           salutation information (default: null)
        :<json str password: new password, must be >=8 characters, mixed case,
           and contain numbers
        :<json str phone: phone number (any reasonable format is okay)
        :<json str thumb: PNG thumbnail for this user, base64 encoded
        :<json int credits: the user credits

        :>header Content-Type: application/json
        :>json str agency: the name of the organization/agency that this person
            is affiliated with (default: null)
        :>json str created: record creation timestamp in ISO-8601 format
        :>json str email: e-mail address
        :>json bool is_admin: true if this user has admin privileges, false
            otherwise
        :>json str location: location name, e.g. city or state (default: null)
        :>json str modified: record modification timestamp in ISO-8601 format
        :>json str name: user's full name, optionally including title or other
            salutation information (default: null)
        :>json str phone: phone number
        :>json str phone_e164: phone number in E.164 format
        :>json str thumb: PNG thumbnail for this user, base64 encoded
        :>json int credits: the user credits
        :>json str url: url to view data about this user

        :status 200: ok
        :status 400: invalid request body
        :status 401: authentication required
        :status 403: not authorized to make the requested changes
        '''

        request_json = request.get_json()
        user = g.db.query(User).filter(User.id == id_).first()

        if not g.user.is_admin and g.user.id != user.id:
            raise Forbidden('You may only modify your own profile.')

        if 'is_admin' in request_json:
            if not g.user.is_admin:
                raise Forbidden('Only admins can change user roles.')

            if g.user.id == int(id_):
                raise BadRequest('You may not modify your own role.')

            user.is_admin = request_json['is_admin']

        if 'credits' in request_json:
            if not g.user.is_admin:
                raise Forbidden('Only admins can change user credits.')

            try:
                user.credits = int(request_json['credits'])
            except ValueError:
                raise ValueError('Credits must be an integer number.')

        self._update_string_field(request_json, 'agency', user, 'agency')
        self._update_string_field(request_json, 'location', user, 'location')
        self._update_string_field(request_json, 'name', user, 'name')

        if 'email' in request_json:
            email = request_json['email'].strip()

            if email == '':
                raise BadRequest('E-mail may not be blank.')

            if '@' not in email and email != 'admin':
                raise BadRequest('Invalid e-mail address.')

            user.email = email

        if 'phone' in request_json:
            if request_json['phone'].strip() == '':
                user.phone = None
            else:
                try:
                    phone = phonenumbers.parse(request_json['phone'], 'US')

                    if not phonenumbers.is_valid_number(phone):
                        raise ValueError()
                except:
                    raise BadRequest('Invalid phone number.')

                user.phone = phonenumbers.format_number(
                    phone, phonenumbers.PhoneNumberFormat.E164)

        if 'thumb' in request_json:
            try:
                img_data = base64.b64decode(request_json['thumb'])
                img = Image.open(BytesIO(img_data))

                if img.format != 'PNG':  # or img.size != (32,32):
                    raise ValueError()
            except:
                raise BadRequest('Thumbnail image must be 32x32 px,'
                                 ' PNG format, base64 encoded.')

            user.thumb = img_data

        if 'password' in request_json:
            password = request_json['password'].strip()

            if not valid_password(password):
                raise BadRequest('Password does not meet complexity '
                                 'requirements.')

            user.password_hash = hash_password(
                password, g.config.get('password_hash', 'algorithm'),
                int(g.config.get('password_hash', 'rounds')))

        g.db.commit()
        g.db.expire(user)

        return jsonify(**self._user_dict(user))
Ejemplo n.º 2
0
    def put(self, id_):
        '''
        Update data about the application identified by `id`. Omitted fields
        are not changed.

        **Example Request**

        .. sourcecode:: json

            {
                "agency": "Department Of Justice",
                "email": "*****@*****.**",
                "is_admin": true,
                "location": "Washington, DC",
                "name": "Lt. John Doe",
                "password": "******",
                "phone": "+12025551234",
                "thumb": "iVBORw0KGgoAAAANS..."
            }

        **Example Response**

        .. sourcecode:: json

            {
                "agency": "Department Of Justice",
                "created": "2015-05-05T14:30:09.676268",
                "email": "*****@*****.**",
                "id": 2029,
                "is_admin": true,
                "location": "Washington, DC",
                "modified": "2015-05-05T14:30:09.676294",
                "name": "Lt. John Doe",
                "phone": "202-555-1234",
                "thumb": "iVBORw0KGgoAAAANS...",
                "url": "https://quickpin/api/user/2029"
            }

        :<header Content-Type: application/json
        :<header X-Auth: the client's auth token
        :>json str agency: the name of the organization/agency that this person
            is affiliated with
        :>json str email: e-mail address
        :>json bool is_admin: true if this user should have admin privileges,
            false otherwise (this field can only be modified by an admin user)
        :>json str location: location name, e.g. city or state (default: null)
        :>json str name: user's full name, optionally including title or other
            salutation information (default: null)
        :>json str password: new password, must be >=8 characters, mixed case,
            and contain numbers
        :>json str phone: phone number (any reasonable format is okay)
        :>json str thumb: PNG thumbnail for this user, base64 encoded

        :>header Content-Type: application/json
        :>json str agency: the name of the organization/agency that this person
            is affiliated with (default: null)
        :>json str created: record creation timestamp in ISO-8601 format
        :>json str email: e-mail address
        :>json bool is_admin: true if this user has admin privileges, false
            otherwise
        :>json str location: location name, e.g. city or state (default: null)
        :>json str modified: record modification timestamp in ISO-8601 format
        :>json str name: user's full name, optionally including title or other
            salutation information (default: null)
        :>json str phone: phone number
        :>json str phone_e164: phone number in E.164 format
        :>json str thumb: PNG thumbnail for this user, base64 encoded
        :>json str url: url to view data about this user

        :status 200: ok
        :status 400: invalid request body
        :status 401: authentication required
        :status 403: not authorized to make the requested changes
        '''

        request_json = request.get_json()
        user = g.db.query(User).filter(User.id == id_).first()

        if not g.user.is_admin and g.user.id != user.id:
            raise Forbidden('You may only modify your own profile.')

        if 'is_admin' in request_json:
            if not g.user.is_admin:
                raise Forbidden('Only admins can change user roles.')

            if g.user.id == int(id_):
                raise BadRequest('You may not modify your own role.')

            user.is_admin = request_json['is_admin']

        self._update_string_field(request_json, 'agency', user, 'agency')
        self._update_string_field(request_json, 'location', user, 'location')
        self._update_string_field(request_json, 'name', user, 'name')

        if 'email' in request_json:
            email = request_json['email'].strip()

            if email == '':
                raise BadRequest('E-mail may not be blank.')

            if '@' not in email and email != 'admin':
                raise BadRequest('Invalid e-mail address.')

            user.email = email

        if 'phone' in request_json:
            if request_json['phone'].strip() == '':
                user.phone = None
            else:
                try:
                    phone = phonenumbers.parse(request_json['phone'], 'US')

                    if not phonenumbers.is_valid_number(phone):
                        raise ValueError()
                except:
                    raise BadRequest('Invalid phone number.')

                user.phone = phonenumbers.format_number(
                    phone,
                    phonenumbers.PhoneNumberFormat.E164
                )

        if 'thumb' in request_json:
            try:
                img_data = base64.b64decode(request_json['thumb'])
                img = Image.open(BytesIO(img_data))

                if img.format != 'PNG':# or img.size != (32,32):
                    raise ValueError()
            except:
                raise BadRequest('Thumbnail image must be 32x32 px,' \
                                 ' PNG format, base64 encoded.')

            user.thumb = img_data

        if 'password' in request_json:
            password = request_json['password'].strip()

            if not valid_password(password):
                raise BadRequest('Password does not meet complexity requirements.')

            user.password_hash = hash_password(
                password,
                g.config.get('password_hash', 'algorithm'),
                int(g.config.get('password_hash', 'rounds'))
            )

        g.db.commit()
        g.db.expire(user)

        return jsonify(**self._user_dict(user))
Ejemplo n.º 3
0
    def post(self):
        '''
        Create a new application user.

        **Example Request**

        .. sourcecode:: json

            {
                "email": "*****@*****.**",
                "password": "******"
            }

        **Example Response**

        .. sourcecode:: json

            {
                "agency": null,
                "created": "2015-05-05T14:30:09.676268",
                "email": "*****@*****.**",
                "id": 2029,
                "is_admin": false,
                "location": null,
                "modified": "2015-05-05T14:30:09.676294",
                "name": null,
                "phone": null,
                "thumb": null,
                "credits": 0,
                "url": "https://quickpin/api/user/2029"
            }

        :<header Content-Type: application/json
        :<header X-Auth: the client's auth token
        :>json str email: e-mail address
        :>json str password: new password, must be >=8 characters, mixed case,

        :>header Content-Type: application/json
        :>json str agency: the name of the organization/agency that this person
            is affiliated with (default: null)
        :>json str created: record creation timestamp in ISO-8601 format
        :>json str email: e-mail address
        :>json bool is_admin: true if this user has admin privileges, false
            otherwise
        :>json str location: location name, e.g. city or state (default: null)
        :>json str modified: record modification timestamp in ISO-8601 format
        :>json str name: user's full name, optionally including title or other
            salutation information (default: null)
        :>json str phone: phone number
        :>json str phone_e164: phone number in E.164 format
        :>json str thumb: PNG thumbnail for this user, base64 encoded
        :>json int credits: the user credits
        :>json str url: url to view data about this user

        :status 200: ok
        :status 400: invalid request body
        :status 401: authentication required
        :status 403: not authorized to create accounts
        :status 409: e-mail address already in use
        '''

        request_json = request.get_json()

        if 'email' not in request_json or '@' not in request_json['email']:
            raise BadRequest('Invalid or missing email.')

        user = User(request_json['email'].strip())

        if 'password' not in request_json:
            raise BadRequest('Password is required')

        password = request_json['password'].strip()

        if not valid_password(password):
            raise BadRequest('Password does not meet complexity requirements.')

        user.password_hash = hash_password(
            password, g.config.get('password_hash', 'algorithm'),
            int(g.config.get('password_hash', 'rounds')))

        try:
            g.db.add(user)
            g.db.commit()
        except IntegrityError:
            raise Conflict('This e-mail address is already in use.')

        g.db.expire(user)

        return jsonify(**self._user_dict(user))
Ejemplo n.º 4
0
    def post(self):
        '''
        Create a new application user.

        **Example Request**

        .. sourcecode:: json

            {
                "email": "*****@*****.**",
                "password": "******"
            }

        **Example Response**

        .. sourcecode:: json

            {
                "agency": null,
                "created": "2015-05-05T14:30:09.676268",
                "email": "*****@*****.**",
                "id": 2029,
                "is_admin": false,
                "location": null,
                "modified": "2015-05-05T14:30:09.676294",
                "name": null,
                "phone": null,
                "thumb": null,
                "url": "https://quickpin/api/user/2029"
            }

        :<header Content-Type: application/json
        :<header X-Auth: the client's auth token
        :>json str email: e-mail address
        :>json str password: new password, must be >=8 characters, mixed case,

        :>header Content-Type: application/json
        :>json str agency: the name of the organization/agency that this person
            is affiliated with (default: null)
        :>json str created: record creation timestamp in ISO-8601 format
        :>json str email: e-mail address
        :>json bool is_admin: true if this user has admin privileges, false
            otherwise
        :>json str location: location name, e.g. city or state (default: null)
        :>json str modified: record modification timestamp in ISO-8601 format
        :>json str name: user's full name, optionally including title or other
            salutation information (default: null)
        :>json str phone: phone number
        :>json str phone_e164: phone number in E.164 format
        :>json str thumb: PNG thumbnail for this user, base64 encoded
        :>json str url: url to view data about this user

        :status 200: ok
        :status 400: invalid request body
        :status 401: authentication required
        :status 403: not authorized to create accounts
        :status 409: e-mail address already in use
        '''

        request_json = request.get_json()

        if 'email' not in request_json or '@' not in request_json['email']:
            raise BadRequest('Invalid or missing email.')

        user = User(request_json['email'].strip())

        if 'password' not in request_json:
            raise BadRequest('Password is required')

        password = request_json['password'].strip()

        if not valid_password(password):
            raise BadRequest('Password does not meet complexity requirements.')

        user.password_hash = hash_password(
            password,
            g.config.get('password_hash', 'algorithm'),
            int(g.config.get('password_hash', 'rounds'))
        )

        try:
            g.db.add(user)
            g.db.commit()
        except IntegrityError:
            raise Conflict('This e-mail address is already in use.')

        g.db.expire(user)

        return jsonify(**self._user_dict(user))