Ejemplo n.º 1
0
async def store(
        form: ZoneCreateForm,
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:create")),
):

    data = only(dict(form), ["ip", "domain"])

    data["domain"] = data["domain"].lower()

    # Make sure domain is unique

    if zone_repo.exists(domain=data["domain"]):
        abort_for_input("domain", "A Zone with that domain already exists")

    zone_repo.clear()

    if form.dns_server_id:
        if dns_server_repo.exists(id=form.dns_server_id):
            data["dns_server_id"] = dns_server_repo.results().id

    if form.http_server_id:
        if http_server_repo.exists(id=form.http_server_id):
            data["http_server_id"] = http_server_repo.results().id

    zone = zone_repo.create(data).data()
    return ZoneResponse(zone=zone)
Ejemplo n.º 2
0
async def store(
    form: DnsRequestCreateForm,
    dns_request_repo: DnsRequestRepo = Depends(DnsRequestRepo()),
    zone_repo: ZoneRepo = Depends(ZoneRepo()),
    dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
    token: str = Depends(ScopedTo("dns-request:create")),
):

    dns_server_id = (
        dns_server_repo.first_or_fail(name=form.dns_server_name.lower()).results().id
    )

    zone = (
        zone_repo.filter(literal(form.name.lower()).contains(zone_repo.label("domain")))
        .first()
        .results()
    )

    zone_id = zone.id if zone else None

    data = only(
        dict(form),
        ["name", "source_address", "source_port", "type", "protocol", "raw_request"],
    )

    data["name"] = data["name"].lower()
    data["type"] = data["type"].upper()

    data["dns_server_id"] = dns_server_id
    data["zone_id"] = zone_id
    logger.info("[email protected] - Creating DNS Request")
    dns_request = dns_request_repo.create(data).data()

    return DnsRequestResponse(dns_request=dns_request)
Ejemplo n.º 3
0
async def index(
        http_server: str,
        sort_qs: SortQS = Depends(SortQS),
        search: str = Query(None),
        pagination: PaginationQS = Depends(PaginationQS),
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:list")),
        includes: List[str] = Query(None),
):

    includes = only(includes, ["http_records"], values=True)

    # Support ability to either submit http_server.name or http_server.id as http_server_id
    zone_http_server_id_label = zone_repo.label("http_server_id")

    try:
        http_server = int(http_server)
        label = zone_http_server_id_label
    except ValueError:
        label = zone_repo.label("http_server.name")

    pg, items = (zone_repo.search(search).loads(includes).filter_or(
        label == http_server, zone_http_server_id_label.is_(None)).sort(
            sort_qs).paginate(pagination).includes(includes).data())
    return ZonesResponse(pagination=pg, zones=items)
Ejemplo n.º 4
0
async def show(
    http_server: str,
    http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
    token: TokenPayload = Depends(ScopedTo("http-server:show")),
    includes: List[str] = Query(None),
):
    includes = only(includes, ["zones"], values=True)

    http_server_id_label = http_server_repo.label("id")

    try:
        http_server = int(http_server)
        label = http_server_id_label
    except ValueError:
        label = http_server_repo.label("name")

    # TODO: is this vulnerable to sql injection?
    item = (
        http_server_repo.loads(includes)
        .filter(label == http_server)
        .first_or_fail()
        .includes(includes)
        .data()
    )

    return HttpServerResponse(http_server=item)
Ejemplo n.º 5
0
async def activate(
        zone_id: int,
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:update")),
):
    zone = zone_repo.get_or_fail(zone_id).update({"is_active": True}).data()
    return ZoneResponse(zone=zone)
Ejemplo n.º 6
0
async def update(
    user_id: int,
    form: UserEditForm,
    user_repo: UserRepo = Depends(UserRepo()),
    token: TokenPayload = Depends(
        ScopedTo("user:update", "super", satisfy="one")),
):

    email = getattr(form, "email", None)
    if email:
        for u in user_repo.new().all().results():
            print("USER:"******"Invalid Email Address",
                            code=422,
                            field="email")

    data = only(form, ["email", "is_active", "is_superuser"])

    if getattr(form, "password", None):
        data["hashed_password"] = hash_password(form.password)

    item = user_repo.new().get_or_fail(user_id).update(data).data()
    return UserResponse(user=item)
Ejemplo n.º 7
0
async def update(
    http_server: str,
    form: HttpServerCreateForm,
    http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
    token: TokenPayload = Depends(ScopedTo("http-server:update")),
):

    data = only(dict(form), ["name"])
    data["name"] = data["name"].lower()

    http_server_id_label = http_server_repo.label("id")

    try:
        http_server = int(http_server)
        label = http_server_id_label
    except ValueError:
        label = http_server_repo.label("name")

    # TODO: is this vulnerable to sql injection?
    item = (
        http_server_repo.filter(label == http_server)
        .first_or_fail()
        .update(data)
        .data()
    )

    return HttpServerResponse(http_server=item)
Ejemplo n.º 8
0
async def update(
        zone_id: int,
        form: ZoneCreateForm,
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        http_server_repo: DnsServerRepo = Depends(HttpServerRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:update")),
        includes: List[str] = Query(None),
):
    data = only(dict(form), ["ip", "domain"])

    if "domain" in data:
        data["domain"] = data["domain"].lower()
        existing_domain = zone_repo.first(domain=data["domain"]).results()
        if existing_domain and existing_domain.id != zone_id:
            abort_for_input("domain", "A Zone with that domain already exists")
        zone_repo.clear()

    if form.dns_server_id is not None:
        if form.dns_server_id is 0:
            data["dns_server_id"] = None
        elif dns_server_repo.exists(id=form.dns_server_id):
            dns_server = dns_server_repo.results()
            data["dns_server"] = dns_server

    if form.http_server_id is not None:
        if form.http_server_id is 0:
            data["http_server_id"] = None
        elif http_server_repo.exists(id=form.http_server_id):
            http_server = http_server_repo.results()
            data["http_server"] = http_server

    zone = (zone_repo.loads(includes).get_or_fail(zone_id).update(
        data).includes(includes).data())
    return ZoneResponse(zone=zone)
Ejemplo n.º 9
0
async def destroy(
        user_id: int,
        user_repo: UserRepo = Depends(UserRepo()),
        token: TokenPayload = Depends(
            ScopedTo("user:create", "super", satisfy="one")),
        user: User = Depends(current_user),
):
    if user_id == user.id:
        abort(403, msg="Cannot deactivate self")

    remaining_supers = len(
        user_repo.filter(
            user_repo.label("is_superuser") == True,
            user_repo.label("is_active") == True,
            user_repo.label("id") != user_id,
        ).all().results())

    if remaining_supers < 1:
        abort(
            403,
            msg="Cannot deactivate user. No other active super users available."
        )

    user_repo.clear()

    messages = [{"text": "Deactivation Succesful", "type": "success"}]
    if not user_repo.exists(id=user_id):
        return BaseResponse(messages=messages)

    user_repo.deactivate(user_id)
    return BaseResponse(messages=messages)
Ejemplo n.º 10
0
async def sync(
        api_token_repo: ApiTokenRepo = Depends(ApiTokenRepo()),
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
        token: TokenPayload = Depends(ScopedTo("api-token:syncable")),
):
    if "api-token" in token.scopes or "api-token:syncable" in token.scopes:
        abort_for_no_server_names(token)
        if (len(token.payload.dns_server_name) > 0
                and len(token.payload.http_server_name) > 0):
            dns_server = create_or_get_dns_server(token, dns_server_repo)
            http_server = create_or_get_http_server(token, http_server_repo)
            api_token_data = create_or_get_api_token_for_all_nodes(
                token, api_token_repo, dns_server, http_server)
        elif len(token.payload.dns_server_name) > 0:
            dns_server = create_or_get_dns_server(token, dns_server_repo)
            api_token_data = create_or_get_api_token_for_dns_server(
                token, api_token_repo, dns_server)

        elif len(token.payload.http_server_name) > 0:
            http_server = create_or_get_http_server(token, http_server_repo)
            api_token_data = create_or_get_api_token_for_http_server(
                token, api_token_repo, http_server)
        else:
            # something went wrong, should not hit
            raise HTTPException(403, detail="Not found")

        return ApiTokenResponse(api_token=api_token_data)

    else:
        raise HTTPException(403, detail="Not found")
Ejemplo n.º 11
0
async def login(
    token: TokenPayload = Depends(ScopedTo("refresh")),
    user: User = Depends(current_user),
):
    token = create_bearer_token(
        data={"sub": token.sub, "scopes": " ".join(token.scopes)}
    )
    return PasswordAuthResponse(token_type="bearer", access_token=str(token))
Ejemplo n.º 12
0
async def activate(
        user_id: int,
        user_repo: UserRepo = Depends(UserRepo()),
        token: TokenPayload = Depends(ScopedTo("user:create", "super")),
):

    user = user_repo.get_or_fail(user_id).update({"is_active": True}).data()
    return UserResponse(user=user)
Ejemplo n.º 13
0
async def index(
        sort_qs: SortQS = Depends(SortQS),
        pagination: PaginationQS = Depends(PaginationQS),
        user_repo: UserRepo = Depends(UserRepo()),
        token: TokenPayload = Depends(ScopedTo("user:list")),
):
    pg, items = user_repo.sort(sort_qs).paginate(pagination).data()
    return UsersResponse(pagination=pg, users=items)
Ejemplo n.º 14
0
async def show(
        user_repo: UserRepo = Depends(UserRepo()),
        token: TokenPayload = Depends(ScopedTo("profile")),
        user: User = Depends(current_user),
):
    logger.critical("Loading user")
    item = user_repo.set_results(user).data()
    return UserResponse(user=item)
Ejemplo n.º 15
0
async def index(
        sort_qs: SortQS = Depends(SortQS),
        pagination: PaginationQS = Depends(PaginationQS),
        http_request_repo: HttpRequestRepo = Depends(HttpRequestRepo()),
        token: TokenPayload = Depends(ScopedTo("http-request:list")),
):
    pg, items = (http_request_repo.loads("http_server").sort(sort_qs).includes(
        "http_server").paginate(pagination).data())
    return HttpRequestsResponse(pagination=pg, http_requests=items)
Ejemplo n.º 16
0
async def destroy(
        api_token_id: int,
        api_token_repo: ApiTokenRepo = Depends(ApiTokenRepo()),
        token: TokenPayload = Depends(ScopedTo("api-token:destroy")),
):
    messages = [{"text": "Deactivation Succesful", "type": "success"}]
    if not api_token_repo.exists(api_token_id):
        return BaseResponse(messages=messages)
    api_token_repo.deactivate(api_token_id)
    return BaseResponse(messages=messages)
Ejemplo n.º 17
0
async def destroy(
        zone_id: int,
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:destroy")),
):
    messages = [{"text": "Deactivation Succesful", "type": "success"}]
    if not zone_repo.exists(zone_id):
        return BaseResponse(messages=messages)
    zone_repo.deactivate(zone_id)
    return BaseResponse(messages=messages)
Ejemplo n.º 18
0
async def show(
        user_id: int,
        user_repo: UserRepo = Depends(UserRepo()),
        token: TokenPayload = Depends(ScopedTo("user:show", "super")),
        includes: List[str] = Query(None),
):
    includes = only(includes, [], values=True)

    item = user_repo.loads(includes).get_or_fail(user_id).includes(
        includes).data()
    return UserResponse(user=item)
Ejemplo n.º 19
0
async def show(
        zone_id: int,
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:show")),
        includes: List[str] = Query(None),
):
    includes = only(includes, ["dns_server", "dns_records", "http_server"],
                    values=True)

    zone = zone_repo.loads(includes).get_or_fail(zone_id).includes(
        includes).data()
    return ZoneResponse(zone=zone)
Ejemplo n.º 20
0
async def index(
        sort_qs: SortQS = Depends(SortQS),
        pagination: PaginationQS = Depends(PaginationQS),
        api_token_repo: ApiTokenRepo = Depends(ApiTokenRepo()),
        token: TokenPayload = Depends(ScopedTo("api-token:list")),
        includes: List[str] = Query(None),
):
    includes = only(includes, ["dns_server", "http_server"], values=True)

    pg, items = (api_token_repo.loads(includes).strict().sort(
        sort_qs).paginate(pagination).includes(includes).data())
    return ApiTokensResponse(pagination=pg, api_tokens=items)
Ejemplo n.º 21
0
async def dig(
        zone_id: int,
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-record:list")),
):
    zone = zone_repo.includes("dns_records").first_or_fail(
        id=zone_id).results()
    print(zone)
    print(zone.dns_records)
    # TODO: fix method
    rrs = RecordParser.from_zone(zone).get_rrs()
    dig = DNSRecord(rr=rrs).toZone()
    return DnsRecordsDigResponse(dig=dig)
Ejemplo n.º 22
0
async def show(
        http_request_id: int,
        http_request_repo: HttpRequestRepo = Depends(HttpRequestRepo()),
        token: TokenPayload = Depends(ScopedTo("http-request:show")),
        includes: List[str] = Query(None),
):
    # probably a bunch of access bypasses with scopes via includes
    # need easy way to scope for includes
    includes = only(includes, ["http_server", "zone"], values=True)

    http_request = (http_request_repo.loads(includes).get_or_fail(
        http_request_id).includes(includes).data())
    return HttpRequestResponse(http_request=http_request)
Ejemplo n.º 23
0
async def index(
        sort_qs: SortQS = Depends(SortQS),
        pagination: PaginationQS = Depends(PaginationQS),
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-server:list")),
        search: str = Query(None),
        includes: List[str] = Query(None),
):
    includes = only(includes, ["zones"], values=True)

    pg, items = (dns_server_repo.loads(includes).includes(includes).search(
        search, searchable=["name", "id"]).paginate(pagination).data())
    return DnsServersResponse(pagination=pg, dns_servers=items)
Ejemplo n.º 24
0
async def store(
        zone_id: int,
        form: DnsRecordForZoneCreateForm,
        dns_record_repo: DnsRecordRepo = Depends(DnsRecordRepo()),
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-record:create")),
):
    zone_repo.exists(id=zone_id, or_fail=True)

    data = only(dict(form), ["record", "sort"])
    data["zone_id"] = zone_id

    item = dns_record_repo.create(data).data()
    return DnsRecordResponse(dns_record=item)
Ejemplo n.º 25
0
async def show(
        api_token_id: int,
        api_token_repo: ApiTokenRepo = Depends(ApiTokenRepo()),
        token: TokenPayload = Depends(ScopedTo("api-token:read")),
        includes: List[str] = Query(None),
):

    includes = only(includes, ["dns_server", "http_server"], values=True)

    if (not api_token_repo.loads(includes).strict().includes(includes).exists(
            api_token_id)):
        raise HTTPException(404, detail="Not found")
    api_token = api_token_repo.data()
    return ApiTokenResponse(api_token=api_token)
Ejemplo n.º 26
0
async def store(
    form: HttpServerCreateForm,
    http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
    token: TokenPayload = Depends(ScopedTo("http-server:create")),
):
    if http_server_repo.exists(name=form.name.lower()):
        abort_for_input("name", "Server name already taken")

    data = only(dict(form), ["name"])

    data["name"] = data["name"].lower()

    item = http_server_repo.create(data).data()
    return HttpServerResponse(http_server=item)
Ejemplo n.º 27
0
async def store(
        form: ApiTokenCreateForm,
        api_token_repo: ApiTokenRepo = Depends(ApiTokenRepo()),
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
        token: TokenPayload = Depends(ScopedTo("api-token:create")),
        user: User = Depends(current_user),
):
    if form.dns_server_id and form.dns_server_id > 0:
        dns_server_name = (dns_server_repo.first_or_fail(
            id=form.dns_server_id).results().name)
    if form.http_server_id and form.http_server_id > 0:
        http_server_name = (http_server_repo.first_or_fail(
            id=form.http_server_id).results().name)
    scopes = []
    for requested_scope in form.scopes.split(" "):
        request_scope_satisfied = False
        for user_token in token.scopes:
            # TODO: double check this, pretty lenient
            # if a:b in a:b:c
            if user_token in requested_scope:
                request_scope_satisfied = True
        if not request_scope_satisfied:
            logger.warning(
                f"[email protected]: Attempt to create unauthorized scope {requested_scope}"
            )
            raise HTTPException(403, detail="unauthorized")
        else:
            scopes.append(requested_scope)

    # TODO: use better randomness

    token = create_bearer_token(
        data={
            "sub": user.id,
            "scopes": " ".join(scopes),
            "dns_server_name": dns_server_name,
            "http_server_name": http_server_name,
        })

    data = {
        "scopes": " ".join(scopes),
        "token": str(token),
        "expires_at": form.expires_at,
        "dns_server_id": form.dns_server_id,
        "http_server_id": form.http_server_id,
    }

    api_token = api_token_repo.create(data).data()
    return ApiTokenResponse(api_token=api_token)
Ejemplo n.º 28
0
async def index(
        sort_qs: SortQS = Depends(SortQS),
        pagination: PaginationQS = Depends(PaginationQS),
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("zone:list")),
        includes: List[str] = Query(None),
):
    # TODO: bypasses a bunch of scopes, find a way to restrict access via scopes
    includes = only(includes, ["dns_server", "dns_records", "http_server"],
                    values=True)

    pg, items = (zone_repo.loads(includes).strict().sort(sort_qs).paginate(
        pagination).includes(includes).data())
    return ZonesResponse(pagination=pg, zones=items)
Ejemplo n.º 29
0
async def sensitive(
        api_token_id: int,
        api_token_repo: ApiTokenRepo = Depends(ApiTokenRepo()),
        token: TokenPayload = Depends(ScopedTo("api-token:read")),
        includes: List[str] = Query(None),
):

    includes = only(includes, ["dns_server", "http_server"], values=True)

    # TODO: require stronger scope
    if not api_token_repo.exists(api_token_id):
        raise HTTPException(404, detail="Not found")
    api_token = (api_token_repo.loads(includes).set_data_model(
        SensitiveApiTokenData).includes(includes).data())
    return SensitiveApiTokenResponse(api_token=api_token)
Ejemplo n.º 30
0
async def index(
        zone_id: int,
        sort_qs: SortQS = Depends(SortQS),
        pagination: PaginationQS = Depends(PaginationQS),
        dns_record_repo: DnsRecordRepo = Depends(DnsRecordRepo()),
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-record:list")),
        includes: List[str] = Query(None),
):
    zone_repo.exists(id=zone_id, or_fail=True)

    includes = only(includes, ["zone"], values=True)

    pg, items = (dns_record_repo.loads("zone").sort(sort_qs).filter_by(
        zone_id=zone_id).paginate(pagination).includes(includes).data())
    return DnsRecordsResponse(pagination=pg, dns_records=items)