Esempio n. 1
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)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
0
def create_or_get_http_server(token: TokenPayload,
                              http_server_repo: HttpServerRepo) -> HttpServer:
    if not http_server_repo.exists(
            name=token.payload.http_server_name.lower()):
        http_server_repo.clear()
        logger.info("[email protected] - Saving http server from api token")
        return http_server_repo.create(
            dict(name=token.payload.http_server_name.lower())).results()
    else:
        return http_server_repo.results()
Esempio n. 5
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)
Esempio n. 6
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)
Esempio n. 7
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)
Esempio n. 8
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")
Esempio n. 9
0
async def index(
    sort_qs: SortQS = Depends(SortQS),
    pagination: PaginationQS = Depends(PaginationQS),
    http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
    token: TokenPayload = Depends(ScopedTo("http-server:list")),
    search: str = Query(None),
    includes: List[str] = Query(None),
):
    includes = only(includes, ["zones"], values=True)

    pg, items = (
        http_server_repo.loads(includes)
        .includes(includes)
        .search(search, searchable=["name", "id"])
        .paginate(pagination)
        .data()
    )
    return HttpServersResponse(pagination=pg, http_servers=items)
Esempio n. 10
0
async def store(
        form: HttpRequestCreateForm,
        http_request_repo: HttpRequestRepo = Depends(HttpRequestRepo()),
        zone_repo: ZoneRepo = Depends(ZoneRepo()),
        http_server_repo: HttpServerRepo = Depends(HttpServerRepo()),
        token: str = Depends(ScopedTo("http-request:create")),
):

    http_server_id = (http_server_repo.first_or_fail(
        name=form.http_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",
            "path",
            "source_address",
            "source_port",
            "type",
            "protocol",
            "raw_request",
        ],
    )

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

    data["http_server_id"] = http_server_id
    data["zone_id"] = zone_id
    logger.info("[email protected] - Creating HTTP Request")
    http_request = http_request_repo.create(data).data()

    return HttpRequestResponse(http_request=http_request)