Ejemplo n.º 1
0
def _set_logo():
    try:
        id = int(request.form['id'])
        get_catalog(id)

        file = request.files['file']
        file_id = upload_image(file, width=64, height=64)
        if file_id is None:
            # Only 64x64 images can be used as a logo
            abort(400)

        cursor = get_db_cursor()
        cursor.execute(
            'DELETE FROM catalog_attribute'
            ' WHERE type=%s AND catalog_id=%s', (
                Attribute.ATTR_LOGO,
                id,
            ))
        cursor.execute(
            'INSERT INTO catalog_attribute (type, catalog_id, value_id)'
            ' VALUES (%s, %s, %s)', (
                Attribute.ATTR_LOGO,
                id,
                file_id,
            ))
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 2
0
def _create_modification():
    error = None
    id = int(request.args['id'])
    catalog = get_catalog(id)
    title = request.json['title']
    title_eng = request.json['title_eng']
    description = request.json['description']
    year = None
    if request.json['year'] != '':
        try:
            year = int(request.json['year'])
            if year < 1500 or year > 2100:
                error = 'Invalid year'
        except:
            error = 'Invalid year'

    if title_eng is None or title_eng == "":
        error = 'title_eng is required'

    if error is not None:
        abort(403)

    try:
        cursor = get_db_cursor()
        catalog_id = create_catalog(cursor, catalog['type'], title, title_eng,
                                    description, year, get_catalog_root(id))

        create_relation(cursor, id, catalog_id, Relation.REL_MODIFICATION)
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 3
0
def confirm_email():
    try:
        email = request.json['email']
        h = request.json['h']
        cursor = get_db_cursor()
        cursor.execute('SELECT * FROM user WHERE email = %s', (email, ))
        user = cursor.fetchone()
        if user is None:
            return jsonify(error='Can\'t find the user.')

        if user['status'] != UserStatus.REGISTERED:
            return jsonify(error='Can\'t enable this user login.')

        hash = user_hash(email, user['id'])
        if h != hash:
            return jsonify(error='Wrong confirmation code.')

        cursor.execute('UPDATE user SET status = %s WHERE id = %s', (
            UserStatus.ACTIVE,
            user['id'],
        ))
        db_commit()
    except:
        return jsonify(error='Internal server error.')

    return jsonify(success='Email was successfully validated.')
Ejemplo n.º 4
0
def _subitem_add():
    id = request.json['id']
    item = get_item(id)
    if not g.user['admin'] or (item['owner_id'] != g.user['id']):
        abort(403)
    try:
        subitem_id = request.json['subitem']
        # assert that subitem exists
        subitem = get_item(subitem_id)
        if not g.user['admin'] or (subitem['owner_id'] != g.user['id']):
            abort(403)
        cursor = get_db_cursor()
        # check whether this item is already included somewhere
        cursor.execute(
            'SELECT * FROM item_relation'
            ' WHERE item_id2 = %s AND type = %s',
            (subitem_id, Relation.REL_INCLUDES))
        if cursor.fetchone() is not None:
            abort(403)
        # check possible recursion
        if id == subitem_id or not check_parent_loops(id, subitem_id):
            abort(403)

        cursor.execute(
            'INSERT INTO item_relation (item_id1, item_id2, type)'
            ' VALUES (%s, %s, %s)', (id, subitem_id, Relation.REL_INCLUDES))
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 5
0
def set_password():
    old_password = request.args.get('old_password').strip()
    new_password = request.args.get('new_password').strip()
    new_password = generate_password_hash(new_password)

    error = None
    if not old_password:
        error = 'Password is required.'

    if not new_password or new_password == '':
        error = 'New password is required.'

    cursor = get_db_cursor()
    cursor.execute('SELECT * FROM user WHERE id = %s', (g.user['id'], ))
    user = cursor.fetchone()

    if not check_password_hash(user['password'], old_password):
        error = 'Incorrect password.'

    if error:
        return jsonify(error=error)

    cursor.execute('UPDATE user SET password = %s WHERE id = %s',
                   (new_password, g.user['id']))
    db_commit()
    return jsonify(result='success')
Ejemplo n.º 6
0
def _upload_image():
    id = request.form.get('id', -1, type=int)
    item = get_item(id)

    if item['owner_id'] != g.user['id']:
        return abort(403)

    if 'file' not in request.files:
        return abort(400)

    file = request.files['file']
    if file:
        file_id = upload_image(file, request.form.get('desc'))
        cursor = get_db_cursor()
        cursor.execute(
            'INSERT INTO item_attribute (type, item_id, value_id)'
            ' VALUES (%s, %s, %s)', (
                Attribute.ATTR_IMAGE,
                id,
                file_id,
            ))
        db_commit()
        cursor.execute('SELECT id, filename FROM image WHERE id = %s',
                       (file_id, ))
        return jsonify(cursor.fetchone())

    return abort(400)
Ejemplo n.º 7
0
def approve():
    id = int(request.args['id'])
    item = get_item(id)

    cursor = get_db_cursor()

    cursor.execute(
        'DELETE FROM catalog_history WHERE id = %s', (id,)
    )
    db_commit()

    return jsonify(result='success')
Ejemplo n.º 8
0
def set_username():
    username = request.args.get('username').strip()
    cursor = get_db_cursor()

    cursor.execute('SELECT id FROM user WHERE username = %s AND id <> %s', (
        username,
        g.user['id'],
    ))
    if cursor.fetchone() is not None:
        return jsonify(
            error='User with name {} is already registered.'.format(username))

    cursor.execute('UPDATE user SET username = %s WHERE id = %s',
                   (username, g.user['id']))
    db_commit()
    return jsonify(result='success')
Ejemplo n.º 9
0
def undo():
    id = int(request.args['id'])
    item = get_item(id)

    if item['field'] == 'create':
        # no cascade delete yet
        abort(403)

    cursor = get_db_cursor()
    cursor.execute(item['undo_query'])
    cursor.execute(
        'DELETE FROM catalog_history WHERE id = %s', (id,)
    )
    db_commit()

    return jsonify(result='success')
Ejemplo n.º 10
0
def _relation_remove():
    id1 = int(request.json['id1'])
    id2 = int(request.json['id2'])
    rel = request.json['rel']
    rel_id = -1
    if rel == 'includes':
        rel_id = Relation.REL_INCLUDES
    elif rel == 'compatible':
        rel_id = Relation.REL_COMPATIBLE
    elif rel == 'produced':
        rel_id = Relation.REL_PRODUCED
    else:
        abort(403)
    cursor = get_db_cursor()
    delete_relation(cursor, id1, id2, rel_id)
    db_commit()
    return jsonify(result='success')
Ejemplo n.º 11
0
def item_add():
    try:
        id = request.json['id']
        comment = request.json['comment']
        user_id = g.user['id']

        cursor = get_db_cursor()
        cursor.execute(
            'INSERT INTO comment (user_id, message)'
            ' VALUES (%s, %s)', (user_id, comment))
        comment_id = cursor.lastrowid
        cursor.execute(
            'INSERT INTO item_comment (comment_id, ref_id)'
            ' VALUES (%s, %s)', (comment_id, id))
        db_commit()
        return jsonify(result='success')
    except:
        abort(400)
Ejemplo n.º 12
0
def _upload_file():
    id = request.form.get('id', -1, type=int)
    get_catalog(id)

    if 'file' not in request.files:
        return abort(400)

    file = request.files['file']
    if file:
        file_id = upload_file(file, request.form.get('desc'))
        cursor = get_db_cursor()
        create_attribute(cursor, id, Attribute.ATTR_ATTACH, file_id)
        db_commit()
        cursor.execute('SELECT id, filename FROM attachment WHERE id = %s',
                       (file_id, ))
        return jsonify(cursor.fetchone())

    return abort(400)
Ejemplo n.º 13
0
def _update():
    id = int(request.args['id'])
    catalog = get_catalog(id)
    try:
        field = request.json['field']
        value = request.json['value']
        if field not in ['title', 'title_eng', 'description', 'year']:
            abort(403)
        if field == 'year':
            if value == "":
                value = None
            else:
                year = int(value)
                if year < 1500 or year > 2100:
                    abort(403)
                value = year
        cursor = get_db_cursor()
        # field is validated, use concatenation here
        cursor.execute('UPDATE catalog SET ' + field + ' = %s WHERE id = %s',
                       (value, id))
        if not g.user['admin']:
            old_value = catalog[field]
            if old_value:
                if field != 'year':
                    old_value = '"' + db_escape_string(old_value) + '"'
            else:
                old_value = 'NULL'
            cursor.execute(
                'INSERT INTO catalog_history'
                ' (catalog_id, user_id, field, value, old_value, undo_query, description)'
                ' VALUES (%s, %s, %s, %s, %s, %s, %s)',
                (id, g.user['id'], field, value, catalog[field],
                 'UPDATE catalog SET %s = %s WHERE id = %s' % (
                     field,
                     old_value,
                     id,
                 ), 'Change %s from %s to %s' %
                 (field, catalog[field], value)))
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 14
0
def _own():
    id = int(request.args['id'])
    catalog = get_catalog(id)

    if not catalog['is_physical'] and not catalog['is_kit']:
        abort(403)

    if not catalog['root']:
        abort(403)

    collection = get_user_collection(g.user['id'])
    try:
        main = request.json["-1"]
        iid = ''
        if 'internal' in main:
            iid = main['internal']
        cursor = get_db_cursor()
        item_id = add_ownership(cursor, id, iid, collection['id'])

        for _, attr in request.json.items():
            subitem = attr['id']
            subid = int(subitem)
            if id == subid:
                continue
            if attr['use']:
                # assert that catalog item exists
                get_catalog(subid)
                iid = ''
                if 'internal' in attr:
                    iid = attr['internal']
                subitem_id = add_ownership_all(cursor, subid, iid,
                                               collection['id'])
                cursor.execute(
                    'INSERT INTO item_relation (item_id1, item_id2, type)'
                    ' VALUES (%s, %s, %s)',
                    (item_id, subitem_id, Relation.REL_INCLUDES))

        db_commit()
    except:
        db_rollback()
        abort(500)

    return jsonify(result='success')
Ejemplo n.º 15
0
def _update():
    id = int(request.args['id'])
    item = get_item(id)
    if not g.user['admin'] or (item['owner_id'] != g.user['id']):
        abort(403)
    try:
        field = request.json['field']
        value = request.json['value']
        if field not in ['internal_id', 'description']:
            abort(403)
        cursor = get_db_cursor()
        # field is validated, use concatenation here
        cursor.execute('UPDATE item SET ' + field + ' = %s WHERE id = %s',
                       (value, id))
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 16
0
def _delete_image():
    id = request.args.get('id', -1, type=int)
    get_catalog(id)

    img = request.args.get('img', -1, type=int)

    if img == -1:
        return abort(400)

    cursor = get_db_cursor()
    cursor.execute(
        'DELETE FROM catalog_attribute WHERE type = %s'
        ' AND catalog_id = %s AND value_id = %s', (
            Attribute.ATTR_IMAGE,
            id,
            img,
        ))
    db_commit()

    return jsonify(result='success')
Ejemplo n.º 17
0
def _delete_image():
    id = request.args.get('id', -1, type=int)
    item = get_item(id)
    if not g.user['admin'] or (item['owner_id'] != g.user['id']):
        return abort(403)

    img = request.args.get('img', -1, type=int)
    if img == -1:
        return abort(400)

    cursor = get_db_cursor()
    cursor.execute(
        'DELETE FROM item_attribute WHERE type = %s'
        ' AND item_id = %s AND value_id = %s', (
            Attribute.ATTR_IMAGE,
            id,
            img,
        ))
    db_commit()

    return jsonify(result='success')
Ejemplo n.º 18
0
def _software_add():
    id = request.json['id']
    item = get_item(id)
    if item['root_title'] != 'Data storage':
        abort(403)
    if not g.user['admin'] or (item['owner_id'] != g.user['id']):
        abort(403)
    try:
        soft_id = request.json['software']
        soft = get_catalog(soft_id)
        if soft['type'] != Type.TYPE_BITS:
            abort(403)
        cursor = get_db_cursor()
        cursor.execute(
            'INSERT INTO catalog_item_relation (catalog_id, item_id, type)'
            ' VALUES (%s, %s, %s)', (soft_id, id, Relation.REL_STORES))
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 19
0
def _create_kit():
    id = int(request.args['id'])
    catalog = get_catalog(id)
    # TODO
    if not catalog['is_physical'] and not catalog['is_kit']:
        abort(403)

    kit_type = Type.TYPE_KIT

    title = request.json['title']
    title_eng = request.json['title_eng']
    if not title_eng:
        abort(403)

    try:
        cursor = get_db_cursor()

        cursor.execute(
            'SELECT c.id FROM catalog c'
            ' LEFT JOIN catalog_relation r'
            '   ON r.catalog_id2 = c.id'
            '   AND r.type = %s'
            ' WHERE title_eng = "Kit" AND r.catalog_id1 IS NULL',
            (Relation.REL_ROOT, ))
        root = cursor.fetchone()

        kit_id = create_catalog(cursor, kit_type, title, title_eng, '', None,
                                root['id'])

        # Add main item into the kit
        create_relation(cursor, kit_id, id, Relation.REL_INCLUDES)
        create_relation(cursor, kit_id, id, Relation.REL_MAIN_ITEM)
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success')
Ejemplo n.º 20
0
def _relation_add():
    id1 = int(request.json['id1'])
    id2 = int(request.json['id2'])
    rel = Relation.get_id(request.json['rel'])

    # check rules
    c1 = get_catalog(id1)
    c2 = get_catalog(id2)

    # don't add anything to root categories
    if not c1['root'] or not c2['root']:
        return error("can't add root category")

    t1 = c1['type']
    t2 = c2['type']

    if rel == Relation.REL_INCLUDES:
        if t1 == Type.TYPE_ABSTRACT:
            # groups may include only within the same root
            if c1['root'] != c2['root']:
                return error("can't add group from different root")
        elif t1 == Type.TYPE_PHYSICAL:
            if t2 not in [Type.TYPE_PHYSICAL, Type.TYPE_BITS]:
                return error("can't add to physical item")
        elif t1 == Type.TYPE_KIT:
            if t2 not in [Type.TYPE_PHYSICAL, Type.TYPE_KIT]:
                return error("can't add to kit")
        else:
            return error("can't set such relation")
        # TODO bits includes bits instead of stores?
    elif rel == Relation.REL_MAIN_ITEM:
        return error("can't set main item")
    elif rel == Relation.REL_MODIFICATION:
        return error("can't set modification")
    elif rel == Relation.REL_STORES:
        if t2 != Type.TYPE_BITS or not t1 in [
                Type.TYPE_PHYSICAL, Type.TYPE_BITS
        ]:
            return error("can't set storage for software")
    elif rel == Relation.REL_COMPATIBLE:
        # first one is platform
        if not t1 in [Type.TYPE_ABSTRACT, Type.TYPE_BITS, Type.TYPE_PHYSICAL]:
            return error("incorrect first item for compatible relation")
        if t2 == Type.TYPE_COMPANY:
            return error("incorrect second item for compatible relation")
    elif rel == Relation.REL_ROOT:
        return error("can't set root relation")
    elif rel == Relation.REL_PRODUCED:
        # first one is company
        if t1 != Type.TYPE_COMPANY or t2 == Type.TYPE_COMPANY:
            return error("first one should be company, and second one not")

    # check loops
    if not check_parent_loops(id1, id2) or id1 == id2:
        return error("there is already relation between items")

    cursor = get_db_cursor()
    create_relation(cursor, id1, id2, rel)
    db_commit()

    return success()
Ejemplo n.º 21
0
def register():
    if not g.user is None:
        return jsonify(error='Please logout before registering')
    try:
        email = request.json['email'].strip()
        username = request.json['username'].strip()
        username = username[:64]
        password = request.json['password'].strip()
        collection_title = request.json['collection_title']
        collection_description = request.json['collection_desc']
    except:
        return jsonify(error='Missing some parameters')

    error = None
    cursor = get_db_cursor()

    if not email or not re.match("[^@]+@[^@]+.[^@]+", email):
        error = 'Valid E-mail is required.'
    elif not username:
        error = 'Username is required.'
    elif not password:
        error = 'Password is required.'
    elif not collection_title:
        error = 'Collection title is required.'
    else:
        cursor.execute('SELECT id FROM user WHERE email = %s', (email, ))
        if cursor.fetchone() is not None:
            error = 'User with email {} is already registered.'.format(email)
        else:
            cursor.execute('SELECT id FROM user WHERE username = %s',
                           (username, ))
            if cursor.fetchone() is not None:
                error = 'User with name {} is already registered.'.format(
                    username)

    if error is None:
        try:
            cursor.execute(
                'INSERT INTO user (email, username, password) VALUES (%s, %s, %s)',
                (email, username, generate_password_hash(password)))
            id = cursor.lastrowid
            cursor.execute(
                'INSERT INTO collection (title, description, owner_id)'
                ' VALUES (%s, %s, %s)',
                (collection_title, collection_description, id))
            session.clear()
            #session['user_id'] = id

            if os.environ.get('FLASK_ENV') != 'development':
                confirm_register(email, id)
            else:
                cursor.execute('UPDATE user SET status = %s WHERE id = %s', (
                    UserStatus.ACTIVE,
                    id,
                ))
            db_commit()
        except:
            return jsonify(error='Internal server error')

        return jsonify(result='success')

    return jsonify(error=error)
Ejemplo n.º 22
0
def _create():
    error = None
    type_id = Type.get_id(request.json['type'])
    if type_id == -1:
        error = 'Invalid type'
    title = request.json['title']
    title_eng = request.json['title_eng']
    description = request.json['description']
    year = None
    if request.json['year'] != '':
        try:
            year = int(request.json['year'])
            if year < 1500 or year > 2100:
                error = 'Invalid year'
        except:
            error = 'Invalid year'

    try:
        parent_id = int(request.json['parent'])
        parent = get_catalog(parent_id)
        root_id = get_catalog_root(parent_id)
        # parent is itself a root
        if root_id is None:
            root_id = parent_id
            #parent_id = -1
    except:
        error = 'Invalid parent id'

    # override root, if specified
    try:
        id = int(request.json['root'])
        if id != -1:
            root = get_catalog(id)
            if root['is_group'] == 0 or root['root']:
                raise Exception
            root_id = id
    except:
        error = 'Invalid root id'

    if parent['is_group'] != 1 and type == Type.TYPE_ABSTRACT:
        error = 'Cannot add group not to group'

    if title_eng is None or title_eng == "":
        error = 'title_eng is required'

    if error is not None:
        # print(error)
        abort(403, error)

    try:
        cursor = get_db_cursor()
        catalog_id = create_catalog(cursor, type_id, title, title_eng,
                                    description, year, root_id)

        if parent_id != -1:
            create_relation(cursor, parent_id, catalog_id,
                            Relation.REL_INCLUDES)
        db_commit()
    except:
        db_rollback()
        abort(403)

    return jsonify(result='success', id=catalog_id)
Ejemplo n.º 23
0
def _join():
    data = request.get_json(force=True)
    cursor = get_db_cursor()
    try:
        id1 = int(data['id1'])
        id2 = int(data['id2'])
        if id1 == id2:
            return error("can't join the item with itself")

        title = data['title']
        title_eng = data['title_eng']
        year = data['year']
        description = data['description']

        if not title_eng or title_eng == '':
            return error("title_eng wasn't specified")
        if not title or title == '':
            title = title_eng

        if year == '':
            year = None

        # assert that catalog items exist
        c1 = get_catalog(id1)
        c2 = get_catalog(id2)

        if c1['company_id'] != c2['company_id']:
            return error("TODO: companies should match")

        if c1['root'] != c2['root']:
            return error("roots should match")

        if c1['type'] != c2['type']:
            return error("types should match")

        if get_catalog_logo_own(id1) or get_catalog_logo_own(id2):
            return error("TODO: can't join items with logo")

        cursor.execute(
            'SELECT * FROM catalog_relation'
            ' WHERE catalog_id1 = %s AND catalog_id2 = %s', (
                id1,
                id2,
            ))
        if cursor.fetchone():
            return error("items relate to each other")

        cursor.execute(
            'SELECT * FROM catalog_history'
            ' WHERE catalog_id = %s OR catalog_id = %s', (
                id1,
                id2,
            ))
        if cursor.fetchone():
            return error('items modifications should be approved or deleted')

        cursor.execute(
            'SELECT * FROM catalog_relation'
            ' WHERE catalog_id1 = %s AND catalog_id2 = %s', (
                id2,
                id1,
            ))
        if cursor.fetchone():
            return error("items relate to each other")

        cursor.execute(
            'SELECT * FROM page_catalog_section'
            ' WHERE parent = %s OR parent = %s', (
                id1,
                id2,
            ))
        if cursor.fetchone():
            return error("can't join page directory items")

        # Set new parameters of the catalog item
        cursor.execute(
            'UPDATE catalog SET title = %s, title_eng = %s, description = %s,'
            ' year = %s'
            ' WHERE id = %s', (
                title,
                title_eng,
                description,
                year,
                id1,
            ))

        # Redirect items
        cursor.execute('UPDATE item SET catalog_id = %s WHERE catalog_id = %s',
                       (
                           id1,
                           id2,
                       ))

        # Redirect attributes
        cursor.execute(
            'UPDATE catalog_attribute SET catalog_id = %s WHERE catalog_id = %s',
            (
                id1,
                id2,
            ))

        # save kit relations to add later
        cursor.execute(
            'SELECT c.id FROM catalog c'
            ' INNER JOIN catalog_relation cr ON c.id = cr.catalog_id1'
            ' WHERE c.type = %s AND cr.catalog_id2 = %s AND cr.type = %s'
            ' AND EXISTS (SELECT * FROM catalog_relation'
            '     WHERE catalog_id1=c.id AND catalog_id2=%s AND type=%s)', (
                Type.TYPE_KIT,
                id2,
                Relation.REL_INCLUDES,
                id1,
                Relation.REL_INCLUDES,
            ))
        kits = cursor.fetchall()

        # Delete duplicate relations
        for rel in range(Relation.REL_END):
            # id2 is main
            cursor.execute(
                'DELETE FROM catalog_relation WHERE catalog_id1 = %s AND type = %s'
                ' AND catalog_id2 IN (SELECT DISTINCT catalog_id2 FROM'
                ' (SELECT * FROM catalog_relation'
                ' WHERE catalog_id1 = %s AND type = %s) AS tmp)', (
                    id2,
                    rel,
                    id1,
                    rel,
                ))
            # id2 is part
            cursor.execute(
                'DELETE FROM catalog_relation WHERE catalog_id2 = %s AND type = %s'
                ' AND catalog_id1 IN (SELECT DISTINCT catalog_id1 FROM'
                ' (SELECT * FROM catalog_relation'
                ' WHERE catalog_id2 = %s AND type = %s) AS tmp)', (
                    id2,
                    rel,
                    id1,
                    rel,
                ))

        # add kits back
        for k in kits:
            create_relation(cursor, k['id'], id1, Relation.REL_INCLUDES)

        # Redirect relations
        cursor.execute(
            'UPDATE catalog_relation SET catalog_id1 = %s WHERE catalog_id1 = %s',
            (
                id1,
                id2,
            ))
        cursor.execute(
            'UPDATE catalog_relation SET catalog_id2 = %s WHERE catalog_id2 = %s',
            (
                id1,
                id2,
            ))

        # Redirect catalog item relations
        cursor.execute(
            'UPDATE catalog_item_relation SET catalog_id = %s WHERE catalog_id = %s',
            (
                id1,
                id2,
            ))

        # Redirect comment relations
        cursor.execute(
            'UPDATE catalog_comment SET ref_id = %s WHERE ref_id = %s', (
                id1,
                id2,
            ))

        # Delete old catalog item
        cursor.execute('DELETE FROM catalog WHERE id = %s', (id2, ))

        # Commit all the changes
        db_commit()

    except:
        db_rollback()
        return error("uknown error")

    return success()