예제 #1
0
파일: views.py 프로젝트: timbortnik/EcoMap
def check_access():
    """Global decorator for each view.
    Checks permissions to access app resources by each user's request.
    Gets dynamic user info(user role, url, request method)from request context.
    :return: nested function returns true or 403
    """
    if 'access_control' not in session:
        session['access_control'] = permission_control.get_dct()
    logger.debug(jsonify(session['access_control']))
    access_rules = session['access_control']
    route = '/' + '/'.join(request.url.split('/')[3:])

    access_result = check_permissions(current_user.role, route, request.method,
                                      access_rules)
    if not access_result['error']:
        access_status = access_result['status']
        logger.info('ACCESS STATUS: %s DETAILS:(url= %s[%s], user ID:%s (%s))',
                    access_status, route, request.method, current_user.uid,
                    current_user.role)
    else:
        logger.debug('ACCESS: FORBIDDEN! DETAILS:(url= %s[%s], '
                     'user ID:%s (%s), errors=%s)' %
                     (route, request.method, current_user.uid,
                      current_user.role, access_result['error']))
        abort(403)
예제 #2
0
def delete_user():
    """Controller for handling deletion of user profile by
    profile owner.
    :return: json object with success message or message with error
    """
    data = request.get_json()
    valid = validator.hash_check(data['hash_sum'])
    if valid['status']:
        user_id = db.get_user_id_by_hash(data['hash_sum'])
        logger.warning(user_id)
        tuple_of_problems = db.get_problem_id_for_del(user_id)
        problem_list = []
        for tuple_with_problem_id in tuple_of_problems:
            problem_list.append(tuple_with_problem_id[0])
        if db.get_user_comments_count(user_id)[0]:
            db.change_comments_to_anon(user_id)
        if problem_list:
            for problem_id in problem_list:
                db.change_problem_to_anon(problem_id)
                db.change_activity_to_anon(problem_id)
            db.delete_user(user_id[0])
            logger.info('User with id %s has been deleted' % user_id[0])
            response = jsonify(msg='success', deleted_user=user_id[0])
        else:
            db.delete_user(user_id[0])
            logger.info('User with id %s has been deleted' % user_id[0])
            response = jsonify(msg='success', deleted_user=user_id[0])
    else:
        response = Response(json.dumps(valid),
                            mimetype='application/json'), 400
    return response
예제 #3
0
def post_problem():
    """Function which adds data from problem form to DB.
    :return: If request data is invalid:
    {'status': False, 'error': [list of errors]}, 400
    If all ok:
    {'added_problem': 'problem_title'
    'problem_id': 'problem_id'}
    """
    if request.method == 'POST' and request.form:
        data = request.form
        logger.warning(json.dumps(request.form))
        logger.info(data)
        valid = validator.problem_post(data)
        if valid['status']:
            logger.debug('Checks problem post validation. %s', valid)
            user_id = current_user.uid
            posted_date = int(time.time())
            last_id = db.problem_post(data['title'], data['content'],
                                      data['proposal'], data['latitude'],
                                      data['longitude'], data['type'],
                                      posted_date, user_id)
            if last_id:
                db.problem_activity_post(last_id, posted_date, user_id)
            logger.debug('New problem post was created with id %s', last_id)
            response = jsonify(added_problem=data['title'], problem_id=last_id)
        else:
            response = Response(json.dumps(valid),
                                mimetype='application/json'), 400
        return response
예제 #4
0
def get_user_problems(user_id):
    """This method retrieves all user's problem from db.
        :returns list of user's problem represented with next objects:
        {"id": 190,
         "title": "name",
         "latitude": 51.419765,
         "longitude": 29.520264,
         "problem_type_id": 1,
         "status": 0,
         "date": "2015-02-24T14:27:22.000Z",
         "severity": '3',
         "is_enabled": 1
        }
    """
    problems_list = []
    problem_tuple = db.get_user_problems(user_id)
    logger.info(problem_tuple)
    for problem in problem_tuple:
        problems_list.append({
            'id': problem[0],
            'title': problem[1],
            'latitude': problem[2],
            'logitude': problem[3],
            'problem_type_id': problem[4],
            'status': problem[5],
            'date': problem[6] * 1000,
            'severity': problem[8],
            'is_enabled': problem[7]
        })
    return Response(json.dumps(problems_list), mimetype='application/json')
예제 #5
0
def check_access():
    """Global decorator for each view.
    Checks user permission to access application resources before each request.
    Gets dynamic request params(user role, url, request method) from each
    request context and compares it with admin permissions stored in db.
    :return: nested function returns true or 403 status and denies access.
    """
    if 'access_control' not in session:
        session['access_control'] = permission_control.get_dct()
    access_rules = session['access_control']
    route = parse_url(request.url)

    access_result = check_permissions(current_user.role, route, request.method,
                                      access_rules)
    if not access_result['error']:
        access_status = access_result['status']
        logger.info('ACCESS STATUS: %s DETAILS:(url= %s[%s], user ID:%s (%s))',
                    access_status, route, request.method, current_user.uid,
                    current_user.role)
    else:
        logger.info('ACCESS: FORBIDDEN! DETAILS:(url= %s[%s],'
                    'user ID:%s (%s), errors=%s)' %
                    (route, request.method, current_user.uid,
                     current_user.role, access_result['error']))
        abort(403)
예제 #6
0
def get_user_problems(user_id):
    """This method retrieves all user's problem from db and shows it in user
    profile page on `my problems` tab.
    :param  user_id: id of user (int).
    :query filtr: name of column for filtration.
    :query order: 0 or 1. 0 - asc and 1 - desc.
    :query limit: limit number. default is 5.
    :query offset: offset number. default is 0.
    :rtype: JSON.
    :return:
        - If user has problems:
            ``[{'id': 190, 'title': 'name',
            'latitude': 51.419765,
            'longitude': 29.520264,
            'problem_type_id': 1,
            'status': 0,
            'date': "2015-02-24T14:27:22.000Z",
            'severity': '3',
            'is_enabled': 1,
            'name': 'problem with forest'
            },{...}]``
        - If user haven't:
            ``{}``
        :statuscode 200: no errors.
    """
    filtr = request.args.get('filtr') or None
    order = int(request.args.get('order')) or 0
    nickname = request.args.get('nickname').encode('utf-8')
    offset = int(request.args.get('offset')) or 0
    per_page = int(request.args.get('per_page')) or 5
    show_role = int(request.args.get('showRole')) or 0
    order_desc = 'asc' if order else 'desc'
    if show_role:
        problem_tuple = db.get_filter_user_by_nickname(nickname, filtr,
                                                       order_desc, offset,
                                                       per_page)
        count = db.count_user_by_nickname(nickname)
    else:
        problem_tuple = db.get_filter_user_nickname(user_id, nickname, filtr,
                                                    order_desc, offset,
                                                    per_page)
        count = db.count_user_by_nickname_for_user(nickname, user_id)
    problems_list = [{
        'id': problem[0],
        'title': problem[1],
        'status': problem[2],
        'date': problem[3] * 1000,
        'is_enabled': problem[4],
        'severity': problem[5],
        'nickname': problem[6],
        'user_id': problem[7],
        'last_name': problem[8],
        'first_name': problem[9],
        'name': problem[10]
    } for problem in problem_tuple] if problem_tuple else []
    logger.info(problem_tuple)
    total_count = {'total_problem_count': count[0]} if count else {}
    return Response(json.dumps([problems_list, [total_count]]),
                    mimetype='application/json')
예제 #7
0
def oauth_login(provider):
    """Provides facebook authorization.
    Retrieves user info from facebook, check if there is
    user with retrieved from facebook user id,
    :param provider: Oauth provider (Facebook by default)

       - if yes:
           skips to next step
       - if not:
           checks if there is user with retrieved email
           - if yes:
               adds oauth credentials to this user
           - if not:
               creates new user
       After all function logging in user into app and return it's params

    """

    access_token_url = 'https://graph.facebook.com/oauth/access_token'
    graph_api_url = 'https://graph.facebook.com/v2.5/me?fields=email,'\
                    'first_name,last_name,id,picture.type(large)'

    params = {
        'client_id': request.json['clientId'],
        'redirect_uri': request.json['redirectUri'],
        'client_secret': app.config['OAUTH_CREDENTIALS']['facebook']['secret'],
        'code': request.json['code']
    }

    resource = requests.get(access_token_url, params=params)
    access_token = dict(parse_qsl(resource.text))
    resource = requests.get(graph_api_url, params=access_token)
    profile = json.loads(resource.text)
    nickname = '{}{}'.format(profile['last_name'], int(time.time()))
    logger.info(profile['picture']['data']['url'])
    user, is_registered = ecomap_user.facebook_register(
        profile['first_name'], profile['last_name'], nickname,
        profile['email'], provider, profile['id'])

    if not db.get_user_avatar(user.uid)[0]:
        db.insert_user_avatar(user.uid, profile['picture']['data']['url'])

    login_user(user, remember=True)

    response = jsonify(iat="???",
                       token=user.get_auth_token(),
                       email=user.email,
                       name=user.first_name,
                       surname=user.last_name,
                       registered=is_registered)

    response.set_cookie('id', bytes(user.uid), max_age=COOKIE_MAX_AGE)
    response.set_cookie('role', bytes(user.role), max_age=COOKIE_MAX_AGE)

    return response
예제 #8
0
파일: views.py 프로젝트: timbortnik/EcoMap
def load_users():
    """Function to check if user is authenticated, else creates
       Anonymous user.
       Launches before requests.
    """
    if current_user.is_authenticated:
        g.user = current_user
    else:
        anon = ecomap_user.Anonymous()
        g.user = anon
    logger.info('current user is %s, %s', g.user.role, g.user)
예제 #9
0
 def create_dct(self):
     """Creates initial instance of permission rules.
     Call sql query and transform it into a json-like object.
     :return:
     """
     parsed_data = {}
     logger.info('<<<Permission Control Initialization>>>')
     all_perms_list = db.get_permission_control_data()
     if all_perms_list:
         parsed_data = [x for x in all_perms_list]
     self.permissions_dict = make_json(parsed_data)
     return self.permissions_dict
예제 #10
0
def load_users():
    """Function-decorator checks if user is authenticated, else creates
       Anonymous user instance.
       Launches before requests.
    """
    if current_user.is_authenticated:
        g.user = current_user
    else:
        anon = ecomap_user.Anonymous()
        g.user = anon
    logger.info('Current user is (%s), role(%s)' %
                (unicode(g.user), g.user.role))
예제 #11
0
def oauth_login(provider):
    """Provides facebook authorization.
       Retrieves user info from facebook, check if there is
       user with retrieved from facebook user id,
       if yes:
           skips to next step
       if not:
           checks if there is user with retrieved email
           if yes:
               adds oauth credentials to this user
           if not:
               creates new user
       After all function loggins user and return it's params
    """

    access_token_url = 'https://graph.facebook.com/oauth/access_token'
    graph_api_url = 'https://graph.facebook.com/v2.5/me?fields=email,'\
                    'first_name,last_name,id,picture.type(large)'

    params = {
        'client_id': request.json['clientId'],
        'redirect_uri': request.json['redirectUri'],
        'client_secret': app.config['OAUTH_CREDENTIALS']['facebook']['secret'],
        'code': request.json['code']
    }

    resource = requests.get(access_token_url, params=params)
    access_token = dict(parse_qsl(resource.text))
    resource = requests.get(graph_api_url, params=access_token)
    profile = json.loads(resource.text)
    logger.info(profile['picture']['data']['url'])

    user = ecomap_user.facebook_register(profile['first_name'],
                                         profile['last_name'],
                                         profile['email'], provider,
                                         profile['id'])

    db.insert_user_avatar(user.uid, profile['picture']['data']['url'])

    login_user(user, remember=True)

    response = jsonify(id=user.uid,
                       name=user.first_name,
                       surname=user.last_name,
                       role=user.role,
                       iat="???",
                       token=user.get_auth_token(),
                       email=user.email)

    return response
예제 #12
0
def subscription_delete():
    """Function deletes data of subscription from DB.
    :type: JSON
    :return: response
    """
    if request.method == 'DELETE':
        logger.info(request.args.get('problem_id'))
        problem_id = int(request.args.get('problem_id'))
        user_id = current_user.uid
        logger.info(problem_id)
        last_id = db.subscription_delete(user_id, problem_id)
        logger.debug('Subscription post was deleted with id %s', last_id)
        response = jsonify(subscription_id=last_id)
        return response
예제 #13
0
def role_permission_put():
    """Function which sets list of permission to role. Before sets
       removes all permissions from role.
       :return: If request data is not invalid':
                    {'status': False, 'error': [list of errors]}
                If all ok:
                    {'msg': 'edited permission'}
    """
    data = request.get_json()
    logger.info('Role permission has been changed.')

    db.delete_permissions_by_role_id(data['role_id'])
    for perm_id in data['permission_id']:
        db.add_role_permission(data['role_id'], perm_id)
    response = jsonify(msg='edited permission')
    session['access_control'] = permission_control.reload_dct()
    return response
예제 #14
0
def post_problem():
    """Function which adds data about created problem into DB.

    :content-type: multipart/form-data

    :fparam title: Title of problem ('problem with rivers')
    :fparam type: id of problem type (2)
    :fparam lat: lat coordinates (49.8256101)
    :fparam longitude: lon coordinates (24.0600542)
    :fparam content: description of problem ('some text')
    :fparam proposal: proposition for solving problem ('text')

    :rtype: JSON
    :return:
            - If request data is invalid:
                    ``{'status': False, 'error': [list of errors]}``
            - If all ok:
                    ``{"added_problem": "problem title", "problem_id": 83}``

    :statuscode 400: request is invalid
    :statuscode 200: problem was successfully posted

    """
    if request.method == 'POST' and request.form:
        data = request.form
        logger.warning(json.dumps(request.form))
        logger.info(data)
        valid = validator.problem_post(data)
        if valid['status']:
            logger.debug('Checks problem post validation. %s', valid)
            user_id = current_user.uid
            posted_date = int(time.time())
            last_id = db.problem_post(data['title'], data['content'],
                                      data['proposal'], data['latitude'],
                                      data['longitude'], data['type'],
                                      posted_date, user_id)
            if last_id:
                db.problem_activity_post(last_id, posted_date, user_id,
                                         'Added')
            logger.debug('New problem post was created with id %s', last_id)
            response = jsonify(added_problem=data['title'], problem_id=last_id)
        else:
            response = Response(json.dumps(valid),
                                mimetype='application/json'), 400
        return response
예제 #15
0
def subscription_post():
    """Function adds data about subscription into DB.
    :param problem_id: id of problem (int)
    :param user_id: id of user (int)
    :param subscr date: date when user subscribed to a problem
    :return: response
    :type: JSON
    """
    if request.method == 'POST':
        data = request.get_json()
        logger.warning(request.get_json())
        logger.info(data)
        user_id = current_user.uid
        subscr_date = int(time.time())
        last_id = db.subscription_post(data['problem_id'], user_id,
                                       subscr_date)
        logger.debug('New subscription post was created with id %s', last_id)
        response = jsonify(subscription_id=last_id)
        return response
예제 #16
0
def get_user_subscriptions_nickname():
    """Function retrieves all user's subscriptions by nickname from db and
    shows it using search field on `my subscriptios` tab.
    :query per_page: limit number. default is 5.
    :query offset: offset number. default is 0.
    :param id: id of subscription (int).
    :param title: title of problem (str).
    :param problem_type_id: id of problem type (int).
    :param status: status of problem (solved or unsolved).
    :param date: date when problem was creared.
    :param date_subscription: date when user subscribed to a problem.
    :param name: name of problem type.
    :last_name: user last name.
    :first_name: user first name.
    :nickname: user nickname.
    :type: JSON
    """
    nickname = request.args.get('nickname').encode('utf-8')
    filtr = request.args.get('filtr')
    order = int(request.args.get('order')) or 0
    offset = int(request.args.get('offset')) or 0
    per_page = int(request.args.get('per_page')) or 5
    order_desc = 'desc' if order else 'asc'
    subscription_tuple = db.get_subscriptions_by_nickname(
        filtr, order_desc, nickname, offset, per_page)
    count = db.count_subscriptions_by_nickname(nickname)
    subscriptions_list = [{
        'id': subscription[0],
        'title': subscription[1],
        'problem_type_id': subscription[2],
        'status': subscription[3],
        'date': subscription[4] * 1000,
        'date_subscription': subscription[5] * 1000,
        'name': subscription[6],
        'last_name': subscription[7],
        'first_name': subscription[8],
        'nickname': subscription[9]
    } for subscription in subscription_tuple]
    logger.info(subscription_tuple)
    total_count = {'total_problem_count': count[0]} if count else {}
    return Response(json.dumps([subscriptions_list, [total_count]]),
                    mimetype='application/json')
예제 #17
0
def get_count_subscriptions():
    """Function retrieves all user's subscriptions from db and shows them in
    `top 10 of the most popular subscriptions` tab.
    :param count: count of subscriptions to every problem (int)
    :param title: title of problem (str)
    :type: JSON
    """
    subscription_tuple = db.count_subscriptions_by_problem_id()
    subscriptions_list = []
    total_count = {}
    logger.info(subscription_tuple)
    for subscription in subscription_tuple:
        subscriptions_list.append({
            'count': subscription[0],
            'id': subscription[1],
            'title': subscription[2]
        })
    sorted_json = sorted(subscriptions_list,
                         key=lambda k: (k['count']),
                         reverse=True)[:10]
    return Response(json.dumps([sorted_json]), mimetype='application/json')
예제 #18
0
def get_user_subscriptions(user_id):
    """Function retrieves all user's subscriptions from db and shows it in user
    profile page on `my subscriptions` tab.
    :param id: id of subscription (int)
    :param title: title of problem (str)
    :param problem_type_id: id of problem type (int)
    :param status: status of problem (solved or unsolved)
    :param date: date when problem was creared
    :param date_subscription: date when user subscribed to a problem
    :param name: name of problem type
    :type: JSON
    """
    filtr = request.args.get('filtr')
    order = int(request.args.get('order')) or 0
    offset = int(request.args.get('offset')) or 0
    per_page = int(request.args.get('per_page')) or 5
    order_desc = 'desc' if order else 'asc'
    subscription_tuple = db.get_subscriptions(user_id, filtr, order_desc,
                                              offset, per_page)
    count = db.count_user_subscriptions(user_id)
    subscriptions_list = []
    total_count = {}
    logger.info(subscription_tuple)
    for subscription in subscription_tuple:
        subscriptions_list.append({
            'id': subscription[0],
            'title': subscription[1],
            'problem_type_id': subscription[2],
            'status': subscription[3],
            'date': subscription[4] * 1000,
            'date_subscription': subscription[5] * 1000,
            'name': subscription[6]
        })
    if count:
        total_count = {'total_problem_count': count[0]}
    return Response(json.dumps([subscriptions_list, [total_count]]),
                    mimetype='application/json')