Skip to content
52 changes: 42 additions & 10 deletions components/renku_data_services/session/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -961,21 +961,28 @@ async def start_build(self, user: base_models.APIUser, build: models.UnsavedBuil
build_orm = schemas.BuildORM(
environment_id=build.environment_id,
status=models.BuildStatus.in_progress,
result_repository_url=build_parameters.repository,
)

launcher = launcher_orm.dump() if launcher_orm is not None else None

params: models.ShipwrightBuildRunParams | None = None
if self.shipwright_client is not None:
params = await self._get_buildrun_params(
user=user, build=build_orm.dump(), build_parameters=build_parameters, launcher=launcher
)
build_orm.result_image = params.output_image
else:
logger.error("Shipwright client is None")

session.add(build_orm)
await session.flush()
await session.refresh(build_orm)

result = build_orm.dump()
launcher = launcher_orm.dump() if launcher_orm is not None else None
result = build_orm.dump()

if self.shipwright_client is not None:
params = await self._get_buildrun_params(
user=user, build=result, build_parameters=build_parameters, launcher=launcher
)
assert params is not None
await self.shipwright_client.create_image_build(params=params, user_id=user.id)
else:
logger.error("Shipwright client is None")

return result

Expand Down Expand Up @@ -1042,6 +1049,26 @@ async def get_build_logs(
authorized = await self._get_environment_authorization(
session=session, user=user, environment=build.environment, scope=Scope.WRITE
)

# If the output image is private, check that the user can read the source repository
if build.result_image is None:
authorized = False
else:
if self.builds_config.private_builds_enabled and build.result_image.startswith(
self.builds_config.build_output_private_image_prefix
):
if build.result_repository_url is None:
authorized = False
else:
repo_data = await self.git_repositories_repo.get_repository(
repository_url=build.result_repository_url,
user=user,
etag=None,
internal_gitlab_user=base_models.APIUser(),
)
if not isinstance(repo_data.metadata, Metadata) or not repo_data.metadata.pull_permission:
authorized = False

if not authorized:
raise errors.MissingResourceError(message=not_found_message)

Expand Down Expand Up @@ -1166,7 +1193,9 @@ async def _get_buildrun_params(
)

if result.is_error:
raise errors.CannotStartBuildError(message=str(result.error))
raise errors.UnauthorizedError(
message=f"You do not have the required credentials to clone the code repository {git_repository}."
)

authentication_secret: models.AuthenticationSecret | None = None
output_image_prefix = self.builds_config.build_output_image_prefix
Expand All @@ -1179,7 +1208,10 @@ async def _get_buildrun_params(
if visibility == RepositoryVisibility.private:
if not self.builds_config.private_builds_enabled:
raise errors.CannotStartBuildError(message="Private repository builds are not enabled")

if isinstance(result.metadata, Metadata) and not result.metadata.pull_permission:
raise errors.ForbiddenError(
message=f"You do not have the required permissions to clone the code repository {git_repository}."
)
token: dict[str, Any] | None = await self.git_repositories_repo.get_token(
repository_url=git_repository, user=user
)
Expand Down
Loading