Ejemplo n.º 1
0
def user_channel_post(channel_name, username):
    new_user_channel = None
    try:
        contact = request.args.get('contact')
        if contact is None or contact == '':
            return error_view(400, "invalid contact")

        channel = Channel.get(channel_name)
        user = User.get(username)

        if UserChannel.exists(user.username, channel.name):
            return error_view(500, "this channel is already linked")

        new_user_channel = UserChannel.new(user.username, channel.name, contact)
        new_user_channel.insert()

        template = CHANNEL_VERIFY_TEMPLATE
        template.set_format(token=new_user_channel.token, channel=channel.name)
        send(contact, channel, template)

        return user_ch_created_view(new_user_channel)

    except (MailSendingError, TelegramSendingError):
        if new_user_channel is not None:
            new_user_channel.delete()

        return error_view(500, "error sending token to this contact")
Ejemplo n.º 2
0
def post():
    try:
        body = request.get_json()
        identity = body.get('identity')
        password = body.get('password')

        if identity is None or identity == '' or password is None or password == '':
            return error_view(400, 'missing parameter')

        if User.exists_from_email(identity):
            # assume identity is email
            user = User.get_from_email(identity)
        else:
            # assume identity is username
            user = User.get(identity)

        if not user.verify_password(password):
            return error_view(401, "error logging in")

        # creating JWT
        # https://flask-jwt-extended.readthedocs.io/en/stable/basic_usage/
        additional_claims = dict(role=user.role)
        access_token = create_access_token(identity=user.username,
                                           additional_claims=additional_claims)

        return token_view(access_token)

    except ObjectNotFound:
        return error_view(404, "error logging in")
Ejemplo n.º 3
0
def put(domain_name):
    try:
        dn = DomainName.get(domain_name)
        ip_address = dn.resolve()
        if ip_address is None:
            return error_view(404, "resolution not found")

        if not IPAddress.exists(ip_address):
            # the DN resolves a new address
            ip = IPAddress.new(ip_address)
            ip.insert()

        if not Resolution.exists(domain_name, ip_address):
            # ip change detected
            resolution = Resolution.new(domain_name, ip_address)
            resolution.insert()

        else:
            resolution = Resolution.get(domain_name, ip_address)
            resolution.update()

        return dn_modified_view(dn)

    except ObjectNotFound as o:
        return error_view(404, str(o))

    except DomainNameResolutionError as dre:
        return error_view(500, str(dre))
Ejemplo n.º 4
0
def post(domain_name):
    try:
        if DomainName.exists(domain_name):
            return error_view(500, f"domain name {domain_name} already exists")

        dn = DomainName.new(domain_name)
        dn.insert()

        ip_address = dn.resolve()

        # in case resolutions went fine
        if ip_address is not None:
            if not IPAddress.exists(ip_address):
                ip = IPAddress.new(ip_address)
                ip.insert()

            resolution = Resolution.new(domain_name, ip_address)
            resolution.insert()

        # create user link
        username = get_jwt_identity()
        user_dn = UserDn.new(username, dn.domain_name, True)
        user_dn.insert()

        return dn_created_view(dn)

    except DomainNameResolutionError as dre:
        return error_view(500, str(dre))
Ejemplo n.º 5
0
def token_check():
    token = request.args.get('token')
    if token is None or token == "":
        return error_view(400, "missing token")

    if UserPending.exists(token):
        return valid_view("valid token")
    else:
        return error_view(400, "invalid token")
Ejemplo n.º 6
0
def user_channel_delete(channel_name, username):
    try:
        if channel_name == Channel.DEFAULT:
            return error_view(500, "cannot unlink default channel")

        user_channel = UserChannel.get(username, channel_name)
        user_channel.delete()
        return user_ch_deleted_view(user_channel)
    except ObjectNotFound:
        return error_view(404, "user channel not found")
Ejemplo n.º 7
0
def put(scheduler_name):
    if not User.exists(scheduler_name):
        return error_view(404, "scheduler not found")

    password = get_password_json()
    if password is None:
        return error_view(400, 'invalid parameter')

    scheduler = User.get(scheduler_name)
    scheduler.update_password(password)

    return scheduler_updated_view(scheduler)
Ejemplo n.º 8
0
def ch_put(name):
    infos = request.json
    if infos is None or infos == '':
        return error_view(400, "missing parameter")

    if not Channel.exists(name):
        return error_view(404, f"channel {name} not found")

    ch = Channel.get(name)
    ch.update(infos)

    return ch_admin_put_view(ch)
Ejemplo n.º 9
0
def ch_delete(name):
    if name == Channel.DEFAULT:
        return error_view(403, f"cannot modify default channel")

    if not Channel.exists(name):
        return error_view(404, f"channel {name} not found")

    ch = Channel.get(name)
    user_channel_list = UserChannel.list_from_channel(ch.name)
    for user_ch in user_channel_list:
        user_ch.delete()

    ch.delete()

    return ch_admin_delete_view(ch)
Ejemplo n.º 10
0
def alert_list_export(dn_list: list, export):
    data = []
    for dn in dn_list:
        data.append([
            dn['domain_name'], dn['domain_name_tags'], dn['last_ip_address'],
            dn['last_ip_tags'], dn['current_ip_address'], dn['current_ip_tags']
        ])

    columns = [
        'Domain name', 'Domain name tags', 'Last IP address', 'Last IP tags',
        'Current IP address', 'Current IP tags'
    ]
    df = pandas.DataFrame(data=data, columns=columns)
    if export == EXPORT_CSV:
        exported_data = df.to_csv(index=False)
        mimetype = "text/csv"

    elif export == EXPORT_JSON:
        exported_data = df.to_json(orient='split', index=False)
        mimetype = "application/json"

    else:
        return error_view(400, "invalid export field")

    return Response(exported_data, headers={"Content-Type": mimetype}), 200
Ejemplo n.º 11
0
def get(domain_name):
    dn = None
    dn_tags = []
    owned = False
    followed = False

    username = get_jwt_identity()
    try:
        dn = DomainName.get(domain_name)
        dn_tags = TagDnIP.list_tags_from_object(dn.domain_name,
                                                DOMAIN_NAME_COLLECTION)

        if not UserDn.exists(username, domain_name):
            owned = False
            followed = False
        else:
            user_dn = UserDn.get(username, domain_name)
            owned = user_dn.owned
            followed = True

        resolution = Resolution.get_current_from_domain(dn.domain_name)

        ip = IPAddress.get(resolution.ip_address)
        ip_tags = TagDnIP.list_tags_from_object(ip.address,
                                                IP_ADDRESS_COLLECTION)

        return dn_retrieved_view(dn, dn_tags, ip, ip_tags, owned, followed)

    except ObjectNotFound as o:
        return error_view(404, str(o))

    except DomainNameResolutionError:
        return dn_retrieved_view(dn, dn_tags, None, [], owned, followed)
Ejemplo n.º 12
0
def post(scheduler_name):
    if User.exists(scheduler_name):
        return error_view(500, "name unavailable")

    password = get_password_json()
    if password is None:
        return error_view(400, 'invalid parameter')

    admin_user = User.get(get_jwt_identity())
    new_scheduler = User.new(scheduler_name,
                             password,
                             admin_user.email,
                             is_scheduler=True)
    new_scheduler.insert()

    return scheduler_created_view(new_scheduler)
Ejemplo n.º 13
0
def get_reverse(ip_address):
    if request.method == 'GET':
        resolution_list = Resolution.list_from_ip(ip_address)
        if len(resolution_list) == 0:
            return error_view(404, "no resolution found for this IP")

        return dn_resolutions_list_view(resolution_list)
Ejemplo n.º 14
0
def check_jwt():
    if request.method == 'GET':
        try:
            token = get_jwt()
            return valid_view("token is valid")
        except Exception:
            return error_view(400, "invalid token")
Ejemplo n.º 15
0
def get_resolutions(domain_name):
    if request.method == 'GET':
        try:
            # return the list of IPs resolved by this domain name
            r = Resolution.get_current_from_domain(domain_name)
            return dn_resolutions_view(r)
        except DomainNameResolutionError as de:
            return error_view(404, str(de))
Ejemplo n.º 16
0
def post(tag_name):
    if Tag.exists(tag_name):
        return error_view(500, "tag already exists")

    new_tag = Tag.new(tag_name)
    new_tag.insert()

    return tag_created_view(new_tag)
Ejemplo n.º 17
0
def remove_user():
    username = request.args.get('username')
    if username is None:
        return error_view(400, "missing username")

    user = User.get(username)
    if user.role != UserRole.ADMIN.value:
        user.delete()

        user_channels = UserChannel.list_from_username(user.username)
        for user_ch in user_channels:
            user_ch.delete()

        return user_deleted_view(user)

    else:
        return error_view(500, "cannot remove an admin user")
Ejemplo n.º 18
0
def request_remove():
    try:
        body = request.json
        if body is None:
            return error_view(400, "invalid JSON in body")

        email = body.get('email')
        if email is None:
            return error_view(400, "invalid email value")

        user_request = UserRequest.get(email)
        user_request.delete()

        return user_request_deleted_view(user_request)

    except ObjectNotFound:
        return error_view(404, "object not found")
Ejemplo n.º 19
0
def delete(tag, object_key, object_type):
    if not TagDnIP.exists(tag, object_key, object_type):
        return error_view(404, "tag link not found")

    tag_link = TagDnIP.get(tag, object_key, object_type)
    tag_link.delete()

    return tag_link_deleted_view(tag_link)
Ejemplo n.º 20
0
def user_channel_put(channel_name, username):
    try:
        token = request.args.get('token')
        if token is None or token == '':
            return error_view(400, 'missing token')

        user_channel = UserChannel.get(username, channel_name)
        if user_channel.verified:
            return error_view(500, 'this channel has already been verified')

        if token != user_channel.token:
            return error_view(500, 'invalid token')

        user_channel.update(verified=True)
        return user_ch_updated_view(user_channel)

    except ObjectNotFound:
        return error_view(404, "user channel not found")
Ejemplo n.º 21
0
def get_list():
    try:
        username = get_jwt_identity()

        input_filter = request.args.get('filter')
        input_filter_by = request.args.get('filter_by')
        sort_by = request.args.get('sort_by')
        limit_str = request.args.get('limit')
        days_str = request.args.get('days')

        export = request.args.get('export')

        params = [input_filter, input_filter_by, sort_by, limit_str, days_str]
        for p in params:
            if p is None:
                return error_view(400, 'missing parameter')

        if not limit_str.isdigit():
            return error_view(400, 'invalid limit')

        if not days_str.isdigit():
            return error_view(400, 'invalid days count')

        limit = int(limit_str)
        days = int(days_str)

        t1 = time()
        dn_list = DomainName.list_recent_changes(
            username, days, input_filter, input_filter_by, sort_by, limit
        )
        t2 = time()
        transaction_time = round(t2 - t1, 2)

        if export is not None and export != '':
            return alert_list_export(dn_list, export)
        else:
            return alert_list(dn_list, transaction_time)

    except DomainNameFilterNotFound:
        return error_view(400, "invalid filter field")

    except DomainNameSortNotFound:
        return error_view(400, "invalid sort field")
Ejemplo n.º 22
0
def manage_domain_name_list():
    if request.method == 'GET':
        try:
            username = get_jwt_identity()

            input_filter = request.args.get('filter')
            input_filter_by = request.args.get('filter_by')
            sort_by = request.args.get('sort_by')
            limit_str = request.args.get('limit')

            export = request.args.get('export')
            owned_filter = request.args.get('owned') is not None
            followed_filter = request.args.get('followed') is not None

            params = [input_filter, input_filter_by, sort_by, limit_str]
            for p in params:
                if p is None:
                    return error_view(400, 'missing parameter')

            if not limit_str.isdigit():
                return error_view(400, 'invalid limit')

            limit = int(limit_str)

            t1 = time()
            dn_list = DomainName.list(username, input_filter, input_filter_by,
                                      owned_filter, followed_filter, sort_by,
                                      limit)
            t2 = time()
            transaction_time = round(t2 - t1, 2)

            if export is not None and export != '':
                # export file data
                return dn_list_export(dn_list, export)
            else:
                # export json data
                return dn_list_view(dn_list, transaction_time)

        except DomainNameFilterNotFound:
            return error_view(400, "invalid filter field")

        except DomainNameSortNotFound:
            return error_view(400, "invalid sort field")
Ejemplo n.º 23
0
def manage_follow(domain_name):
    domain_name = refang(domain_name)
    username = get_jwt_identity()

    if request.method == 'POST':
        if UserDn.exists(username, domain_name):
            return error_view(500, "you are already following this DN")

        user_dn = UserDn.new(username, domain_name, False)
        user_dn.insert()
        return valid_view("DN added to your follows")

    elif request.method == 'DELETE':
        if not UserDn.exists(username, domain_name):
            return error_view(404, "you are not following thiS DN")

        user_dn = UserDn.get(username, domain_name)
        user_dn.delete()
        return valid_view("DN removed from your follows")
Ejemplo n.º 24
0
def channel_test(channel_name):
    try:
        username = get_jwt_identity()
        if request.method == 'GET':
            user = User.get(username)
            channel = Channel.get(channel_name)
            user_channel = UserChannel.get(user.username, channel.name)

            template = TEST_TEMPLATE
            template.set_format(date=str(datetime.now().date()))
            send(user_channel.contact, channel, template)

            return user_ch_test_view(user_channel)

    except ObjectNotFound:
        return error_view(404, "object not found")

    except (MailSendingError, TelegramSendingError):
        return error_view(500, "failed to send test")
Ejemplo n.º 25
0
def manage_tag_dn_ip_list():
    object_key = request.args.get('object')
    object_type = request.args.get('type')

    params = [object_key, object_type]
    for p in params:
        if p is None or p == '':
            return error_view(400, "invalid parameter")

    tag_linked_list = TagDnIP.list_tags_from_object(object_key, object_type)
    return tag_link_list_view(tag_linked_list)
Ejemplo n.º 26
0
def delete(domain_name):
    try:
        username = get_jwt_identity()
        if not UserDn.exists(username, domain_name):
            return error_view(403, "no ownership found")

        # remove ownership
        user_dn = UserDn.get(username, domain_name)
        if not user_dn.owned:
            return error_view(403, "you do not own this domain")

        user_dn.delete()

        # remove tags
        dn_linked_tags = TagDnIP.list_tags_from_object(domain_name,
                                                       DOMAIN_NAME_COLLECTION)
        for t in dn_linked_tags:
            t.delete()

        # remove resolution / IP
        resolution_list = Resolution.list_from_domain(domain_name)
        for r in resolution_list:
            r.delete()

            ip_address = r.ip_address
            res_ip_list = Resolution.list_from_ip(ip_address)
            if len(res_ip_list) == 0:
                ip_linked_tags = TagDnIP.list_tags_from_object(
                    ip_address, IP_ADDRESS_COLLECTION)
                for t in ip_linked_tags:
                    t.delete()

                ip = IPAddress.get(ip_address)
                ip.delete()

        dn = DomainName.get(domain_name)
        dn.delete()

        return dn_deleted_view(dn)
    except ObjectNotFound as o:
        return error_view(404, str(o))
Ejemplo n.º 27
0
def delete(tag_name):
    if not Tag.exists(tag_name):
        return error_view(404, "tag not found")

    tag = Tag.get(tag_name)
    tag.delete()

    tag_links = TagDnIP.list_from_tag(tag.name)
    for t in tag_links:
        t.delete()

    return tag_deleted_view(tag)
Ejemplo n.º 28
0
def post(tag_name, object_key, object_type):
    if TagDnIP.exists(tag_name, object_key, object_type):
        return error_view(500, "tag link already exists")

    if not Tag.exists(tag_name):
        return error_view(404, "source tag not found")

    if object_type == DOMAIN_NAME_COLLECTION:
        object_exists = DomainName.exists(object_key)
    elif object_type == IP_ADDRESS_COLLECTION:
        object_exists = IPAddress.exists(object_key)
    else:
        return error_view(400, "invalid object type")

    if not object_exists:
        return error_view(404, "target object not found")

    new_tag_link = TagDnIP.new(tag_name, object_key, object_type)
    new_tag_link.insert()

    return tag_link_created_view(new_tag_link)
Ejemplo n.º 29
0
def request_access():
    body = request.json
    if body is None:
        return error_view(400, "invalid JSON in body")

    email = body.get('email')
    if email is None:
        return error_view(400, "invalid email value")

    if User.exists_from_email(email):
        return error_view(500, "email unavailable")

    if UserPending.exists_from_email(email):
        return error_view(500, "an invitation has already been sent to this email")

    if UserRequest.exists(email):
        return error_view(500, "a request for this email has already been sent")

    user_request = UserRequest.new(email)
    user_request.insert()

    return user_request_created_view(user_request)
Ejemplo n.º 30
0
def ch_post(name):
    try:
        ch_type = request.args.get('type')
        if ch_type is None or ch_type == '':
            return error_view(400, "missing parameter")

        infos = request.json
        if infos is None or infos == '':
            return error_view(400, "missing json")

        if Channel.exists(name):
            return error_view(500, "a channel with this name already exists")

        new_ch = Channel.new(name, ch_type, infos)
        new_ch.insert()

        return ch_admin_post_view(new_ch)

    except KeyError:
        return error_view(500, "error parsing json input")

    except ChannelTypeError:
        return error_view(400, "invalid channel type")