Exemplo 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)
Exemplo n.º 2
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)
Exemplo n.º 3
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)
Exemplo n.º 4
0
def create_or_get_dns_server(token: TokenPayload,
                             dns_server_repo: DnsServerRepo) -> DnsServer:
    if not dns_server_repo.exists(name=token.payload.dns_server_name.lower()):
        dns_server_repo.clear()
        logger.info("[email protected] - Saving dns server from api token")
        return dns_server_repo.create(
            dict(name=token.payload.dns_server_name.lower())).results()
    else:
        return dns_server_repo.results()
Exemplo n.º 5
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)
Exemplo n.º 6
0
async def store(
        form: DnsServerCreateForm,
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-server:create")),
):
    if dns_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 = dns_server_repo.create(data).data()
    return DnsServerResponse(dns_server=item)
Exemplo n.º 7
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)
Exemplo 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")
Exemplo n.º 9
0
async def show(
        dns_server: str,
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-server:show")),
        includes: List[str] = Query(None),
):
    includes = only(includes, ["zones"], values=True)

    dns_server_id_label = dns_server_repo.label("id")

    try:
        dns_server = int(dns_server)
        label = dns_server_id_label
    except ValueError:
        label = dns_server_repo.label("name")

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

    return DnsServerResponse(dns_server=item)
Exemplo n.º 10
0
async def update(
        dns_server: str,
        form: DnsServerCreateForm,
        dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()),
        token: TokenPayload = Depends(ScopedTo("dns-server:update")),
):

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

    dns_server_id_label = dns_server_repo.label("id")

    try:
        dns_server = int(dns_server)
        label = dns_server_id_label
    except ValueError:
        label = dns_server_repo.label("name")

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

    return DnsServerResponse(dns_server=item)
Exemplo n.º 11
0
    def seed_from_env(self):
        from boucanpy.core.user import UserRepo
        from boucanpy.core.zone import ZoneRepo
        from boucanpy.core.dns_server import DnsServerRepo
        from boucanpy.db.session import _scoped_session

        session = _scoped_session

        for i in range(9):
            i = str(i)
            user_data = {}
            email_key = f"SEED_USER_{i}_EMAIL"
            email = environ.get(email_key, None)
            password_key = f"SEED_USER_{i}_PASSWORD"
            password = environ.get(password_key, None)
            superuser_key = f"SEED_USER_{i}_SUPERUSER"
            is_superuser = int(environ.get(superuser_key, 0))
            if email and password:
                email = email.lower()
                hashed_password = hash_password(password)
                repo = UserRepo(db=session)
                if not repo.exists(email=email):
                    logger.info(
                        f"seed_from_env@api_server.py - seeding user {email}")
                    user = factory("UserFactory", session=session).create(
                        email=email,
                        hashed_password=hashed_password,
                        is_superuser=is_superuser,
                    )
                else:
                    logger.info(
                        f"seed_from_env@api_server.py - Seeded user {email} already exists"
                    )

        for i in range(9):
            i = str(i)
            name_key = f"SEED_DNS_SERVER_{i}_NAME"
            name = environ.get(name_key, None)
            if name:
                repo = DnsServerRepo(db=session)
                if not repo.exists(name=name):
                    logger.info(
                        f"seed_from_env@api_server.py - Seeding domain {name}")
                    domain = factory("DnsServerFactory",
                                     session=session).create(name=name)

        for i in range(9):
            i = str(i)
            ip_key = f"SEED_ZONE_{i}_IP"
            domain_key = f"SEED_ZONE_{i}_DOMAIN"
            dns_server_name_key = f"SEED_ZONE_{i}_DNS_SERVER_NAME"
            ip = environ.get(ip_key, None)
            domain = environ.get(domain_key, None)
            if domain:
                domain = domain.lower()
            dns_server_name = environ.get(dns_server_name_key, None)
            if ip and domain:
                if dns_server_name:
                    dns_server_repo = DnsServerRepo(db=session)
                    if dns_server_repo.exists(name=dns_server_name):
                        dns_server = dns_server_repo.results()
                    else:
                        logger.info(
                            f"seed_from_env@api_server.py - Seeding dns server as zone dependency: {name}"
                        )
                        dns_server = factory(
                            "DnsServerFactory",
                            session=session).create(name=dns_server_name)
                    factory("ZoneFactory",
                            session=session).create(ip=ip,
                                                    domain=domain,
                                                    dns_server=dns_server)
                else:
                    repo = ZoneRepo(db=session)
                    if not repo.exists(ip=ip, domain=domain):
                        logger.info(
                            f"seed_from_env@api_server.py - Seeding zone without dns server: {ip}, {domain}"
                        )
                        factory("GlobalZoneFactory",
                                session=session).create(ip=ip, domain=domain)