Esempio n. 1
0
def users_person_signup_new():
    """
        ---
        post:
          summary: Allows a person to sign up (first step)
          tags:
            - Users
          description:
            Creates a new person (unconfirmed, with no access rights and without access to any account) and sends a welcome e-mail.
          parameters:
            - name: "body"
              in: body
              description: "Person data"
              required: true
              schema:
                "$ref": '#/definitions/PersonSignupNewPOST'
          responses:
            204:
              description: Request was accepted
            400:
              description: Invalid parameters
            403:
              description: Signup disabled
    """
    if os.environ.get('ENABLE_SIGNUP',
                      'false').lower() not in ['true', 'yes', 'on', '1']:
        return "Signup disabled", 403

    if os.environ.get('SIGNUP_DISALLOW_TOR',
                      'true').lower() in ['true', 'yes', 'on', '1']:
        # if user is coming from Tor exit node, disallow signup:
        client_ip = flask.request.environ.get('HTTP_X_FORWARDED_FOR', None)
        if not client_ip:
            return "Could not determine client IP", 403
        if _is_tor_exit_node(client_ip):
            return "Sorry, Tor exit nodes are not allowed to signup due to abuse", 403

    user_id, confirm_pin = Person.signup_new(flask.request.get_json())
    person_data = Person.get(user_id)

    mail_subject = "Welcome to Grafolean!"
    # unless explicitly set otherwise, assume that backend and frontend have the same origin:
    frontend_origin = os.environ.get('FRONTEND_ORIGIN',
                                     flask.request.url_root).rstrip('/')
    mail_body_text = _generate_signup_mail_message(person_data['name'],
                                                   person_data['email'],
                                                   frontend_origin, user_id,
                                                   confirm_pin)

    msg = Message(mail_subject,
                  sender="*****@*****.**",
                  recipients=[person_data['email']],
                  body=mail_body_text)
    mail = Mail(flask.current_app)
    with mail.record_messages() as outbox:
        mail.send(msg)
        flask.g.outbox = outbox  # make sent messages accessible to tests

    return "", 204
Esempio n. 2
0
def users_persons():
    """
        ---
        get:
          summary: Get all persons
          tags:
            - Users
          description:
            Returns a list of all persons. The list is returned in a single array (no pagination).
          responses:
            200:
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      list:
                        type: array
                        items:
                          "$ref": '#/definitions/PersonGET'
        post:
          summary: Create a person account
          tags:
            - Users
          description:
            Creates a person account. By default (as any user) a person is without permissions, so they must be granted to it before it can do anything useful.
          parameters:
            - name: "body"
              in: body
              description: "Person data"
              required: true
              schema:
                "$ref": '#/definitions/PersonPOST'
          responses:
            201:
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      id:
                        type: integer
    """
    if flask.request.method in ['GET', 'HEAD']:
        rec = Person.get_list()
        return json.dumps({'list': rec}), 200

    elif flask.request.method == 'POST':
        person = Person.forge_from_input(flask.request.get_json())
        user_id = person.insert()
        mqtt_publish_changed([
            'persons',
        ])
        return json.dumps({
            'id': user_id,
        }), 201
Esempio n. 3
0
def users_person_forgot_password():
    """
        ---
        post:
          summary: Sends an email with a reset password link
          tags:
            - Users
          description:
            If given an existing e-mail address, sends an e-mail message with a password reset link.
          parameters:
            - name: "body"
              in: body
              description: "E-mail address"
              required: true
              schema:
                "$ref": '#/definitions/ForgotPasswordPOST'
          responses:
            204:
              description: Request was accepted
            400:
              description: Invalid parameters
            500:
              description: Mail sending not setup
    """
    if not flask.current_app.config.get('MAIL_SERVER', None):
        return "Mail sending not setup", 500

    user_id, confirm_pin = Person.forgot_password(flask.request.get_json())
    if not user_id:
        return "Email does not correspond to any registered user", 400

    person_data = Person.get(user_id)
    mail_subject = "Grafolean password reset link"
    # unless explicitly set otherwise, assume that backend and frontend have the same origin:
    frontend_origin = os.environ.get('FRONTEND_ORIGIN',
                                     flask.request.url_root).rstrip('/')
    mail_body_text = _generate_forgot_password_message(frontend_origin,
                                                       user_id, confirm_pin)

    msg = Message(mail_subject,
                  sender="*****@*****.**",
                  recipients=[person_data['email']],
                  body=mail_body_text)
    mail = Mail(flask.current_app)
    with mail.record_messages() as outbox:
        mail.send(msg)
        flask.g.outbox = outbox  # make sent messages accessible to tests

    return "", 204
Esempio n. 4
0
def users_person_forgot_password_reset():
    """
        ---
        post:
          summary: Resets a forgotten password
          tags:
            - Users
          description:
            Resets person's password if person exists, confirmation pin is correct and less than 1 hour old and person account is confirmed.
          parameters:
            - name: "body"
              in: body
              description: "E-mail address"
              required: true
              schema:
                "$ref": '#/definitions/ForgotPasswordResetPOST'
          responses:
            204:
              description: Password was reset
            400:
              description: Invalid parameters
    """
    success = Person.forgot_password_reset(flask.request.get_json())
    if success:
        return "", 204
    else:
        return "Password could not be changed - expired / invalid pin or user does not exist", 400
Esempio n. 5
0
def users_person_signup_complete():
    """
        ---
        post:
          summary: Complete the signup process
          tags:
            - Users
          description:
            Completes the user's signup process by supplying a valid confirmation pin and a new password.
          parameters:
            - name: "body"
              in: body
              description: "Pin and password"
              required: true
              schema:
                "$ref": '#/definitions/PersonSignupCompletePOST'
          responses:
            204:
              description: Pin is valid
            400:
              description: Invalid parameters
            403:
              description: Signup disabled
    """
    if os.environ.get('ENABLE_SIGNUP',
                      'false').lower() not in ['true', 'yes', 'on', '1']:
        return "Signup disabled", 403

    status = Person.signup_complete(flask.request.get_json(),
                                    create_account=True)
    if status:
        return "", 204
    else:
        return "Invalid pin, invalid user id, or signup already completed", 400
Esempio n. 6
0
def users_person_signup_validatepin():
    """
        ---
        post:
          summary: Checks if confirmation pin is valid
          tags:
            - Users
          description:
            Checks if confirmation pin is valid (but doesn't complete the signup yet). This allows
            frontend to ask for a password before completing the signup process.
          parameters:
            - name: "body"
              in: body
              description: "Pin"
              required: true
              schema:
                "$ref": '#/definitions/PersonSignupValidatePinPOST'
          responses:
            204:
              description: Pin is valid
            400:
              description: Invalid parameters
            403:
              description: Signup disabled
    """
    if os.environ.get('ENABLE_SIGNUP',
                      'false').lower() not in ['true', 'yes', 'on', '1']:
        return "Signup disabled", 403

    confirm_pin_valid = Person.signup_pin_valid(flask.request.get_json())
    if confirm_pin_valid:
        return "", 204
    else:
        return "Invalid pin, invalid user id, or signup already completed", 400
Esempio n. 7
0
def admin_first_post():
    """
        ---
        post:
          summary: Create first admin user
          tags:
            - Admin
          description:
            This endpoint helps with setting up a new installation. It allows us to set up just one initial
            admin access (with name, email and password). Later requests to the same endpoint will fail.
            At the same time a systemwide (ICMP ping) bot is configured and its token shared via file with
            a grafolean-ping-bot Docker container (in default setup).
          parameters:
            - name: "body"
              in: body
              description: "First admin data and credentials"
              required: true
              schema:
                "$ref": '#/definitions/PersonPOST'
          responses:
            201:
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: "User id of created admin"
            401:
              description: System already initialized
    """
    if Auth.first_user_exists():
        return 'System already initialized', 401
    admin = Person.forge_from_input(flask.request.get_json())
    admin_id = admin.insert()
    # make it a superuser:
    permission = Permission(admin_id, None, None)
    permission.insert(None, skip_checks=True)

    # Help users by including a systemwide ping bot in the package by default:
    Bot.ensure_default_systemwide_bots_exist()

    mqtt_publish_changed(['status/info'])
    return json.dumps({
        'id': admin_id,
    }), 201
Esempio n. 8
0
def profile():
    user_id = flask.g.grafolean_data['user_id']
    user_is_bot = flask.g.grafolean_data['user_is_bot']
    if user_is_bot:
        tied_to_account = Bot.get_tied_to_account(user_id)
        return json.dumps({
            'user_id':
            user_id,
            'user_type':
            'bot',
            'record':
            Bot.get(user_id, tied_to_account=tied_to_account),
        }), 200
    else:
        return json.dumps({
            'user_id': user_id,
            'user_type': 'person',
            'record': Person.get(user_id),
        }), 200
Esempio n. 9
0
__author__ = 'Justice Ndou'
__website__ = 'http://jobcloud.freelancing-seo.com/'
__email__ = '*****@*****.**'

import os
import webapp2
import jinja2
from ConstantsAndErrorCodes import MyConstants, ErrorCodes, isGoogleServer
from google.appengine.ext import db
from datatypes import Reference, Person
from google.appengine.api import mail
import logging
from google.appengine.api import users
User = Person()
# Jinja Loader
template_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.getcwd()))

scripts = '''
        <link href="http://freelancing-solutions.freelancing-seo.com/jQueryAssets/jquery.ui.core.min.css" rel="stylesheet" type="text/css">
        <link href="http://freelancing-solutions.freelancing-seo.com/jQueryAssets/jquery.ui.theme.min.css" rel="stylesheet" type="text/css">
        <link href="http://freelancing-solutions.freelancing-seo.com/jQueryAssets/jquery.ui.tabs.min.css" rel="stylesheet" type="text/css">


		<script src="http://freelancing-solutions.freelancing-seo.com/js/jquery.min.js"></script>
		<script src="http://freelancing-solutions.freelancing-seo.com/js/config.js"></script>
		<script src="http://freelancing-solutions.freelancing-seo.com/js/skel.min.js"></script>
		<script src="http://freelancing-solutions.freelancing-seo.com/js/skel-panels.min.js"></script>
	<noscript>
			<link rel="stylesheet" href="http://freelancing-solutions.freelancing-seo.com/css/skel-noscript.css" />
			<link rel="stylesheet" href="http://freelancing-solutions.freelancing-seo.com/css/style.css" />
Esempio n. 10
0
def users_person_change_password(user_id):
    rowcount = Person.change_password(user_id, flask.request.get_json())
    if not rowcount:
        return "Change failed", 400
    # no need to publish to mqtt - nobody cares
    return "", 204
Esempio n. 11
0
def users_person_crud(user_id):
    """
        ---
        get:
          summary: Get person data
          tags:
            - Users
          description:
            Returns person data.
          parameters:
            - name: user_id
              in: path
              description: "User id"
              required: true
              schema:
                type: integer
          responses:
            200:
              content:
                application/json:
                  schema:
                    "$ref": '#/definitions/PersonGETWithPermissions'
            404:
              description: No such person
        put:
          summary: Update the bot
          tags:
            - Users
          description:
            Updates person data.
          parameters:
            - name: user_id
              in: path
              description: "User id"
              required: true
              schema:
                type: integer
            - name: "body"
              in: body
              description: "Person data"
              required: true
              schema:
                "$ref": '#/definitions/PersonPOST'
          responses:
            204:
              description: Update successful
            404:
              description: No such person
        delete:
          summary: Remove the person data
          tags:
            - Users
          description:
            Removes the person data. Also removes user's permissions, if any.
          parameters:
            - name: user_id
              in: path
              description: "User id"
              required: true
              schema:
                type: integer
          responses:
            204:
              description: Person data removed successfully
            403:
              description: Can't remove yourself
            404:
              description: No such person
    """
    if flask.request.method in ['GET', 'HEAD']:
        rec = Person.get(user_id)
        if not rec:
            return "No such person", 404
        rec['permissions'] = Permission.get_list(user_id)
        return json.dumps(rec), 200

    elif flask.request.method == 'PUT':
        person = Person.forge_from_input(flask.request.get_json(),
                                         force_id=user_id)
        rowcount = person.update()
        if not rowcount:
            return "No such person", 404
        mqtt_publish_changed([
            'persons/{user_id}'.format(user_id=user_id),
            'persons',
        ])
        return "", 204

    elif flask.request.method == 'DELETE':
        # user should not be able to delete himself, otherwise they could lock themselves out:
        if int(flask.g.grafolean_data['user_id']) == int(user_id):
            return "Can't delete yourself", 403
        rowcount = Person.delete(user_id)
        if not rowcount:
            return "No such person", 404
        mqtt_publish_changed([
            'persons/{user_id}'.format(user_id=user_id),
            'persons',
        ])
        return "", 204