syncData(); $this->getPrivateKeys(); $this->getSources(); } catch (\Throwable $e) { handleError($e, $this); } } public function updatedGitRepository() { $this->gitRepository = trim($this->gitRepository); } public function updatedGitBranch() { $this->gitBranch = trim($this->gitBranch); } public function updatedGitCommitSha() { $this->gitCommitSha = trim($this->gitCommitSha); } private function syncData(bool $toModel = false): void { if ($toModel) { $this->validate(); $this->application->fill([ 'git_repository' => $this->gitRepository, 'git_branch' => $this->gitBranch, 'git_commit_sha' => $this->gitCommitSha, 'private_key_id' => $this->privateKeyId, ]); if (filled($this->gitHttpsPassword)) { $this->application->git_https_username = $this->gitHttpsUsername; $this->application->git_https_password = $this->gitHttpsPassword; } elseif ($this->hasGitHttpsPassword) { $this->application->git_https_username = $this->gitHttpsUsername; } $this->application->save(); // Refresh to get the trimmed values from the model $this->application->refresh(); $this->syncData(false); } else { $this->gitRepository = $this->application->git_repository; $this->gitBranch = $this->application->git_branch; $this->gitCommitSha = $this->application->git_commit_sha; $this->privateKeyId = $this->application->private_key_id; $this->privateKeyName = data_get($this->application, 'private_key.name'); $this->gitHttpsUsername = $this->application->git_https_username; $this->gitHttpsPassword = null; $this->hasGitHttpsPassword = filled($this->application->git_https_password); } } /** * Other keys and sources of the team. Users without write access on the whole team keep the ones the * application already uses, so they only see those. */ private function canUseTeamCredentials(): bool { return Gate::allows('useTeamCredentials', $this->application); } private function getPrivateKeys() { if (! $this->canUseTeamCredentials()) { $this->privateKeys = collect(); return; } $this->privateKeys = PrivateKey::where('team_id', $this->application->team()->id)->get()->reject(function ($key) { return $key->id == $this->privateKeyId; }); } private function getSources() { if (! $this->canUseTeamCredentials()) { $this->sources = collect(); return; } $this->sources = $this->application->team()->sources()->filter(function ($source) { if ($source->id === $this->application->source_id && $source->getMorphClass() === $this->application->source_type) { return false; } if ($source instanceof GithubApp) { return ! is_null($source->app_id); } if ($source instanceof GitlabApp || $source instanceof GiteaApp) { return $source->isConnected(); } return true; })->sortBy('name'); } public function setPrivateKey(int $privateKeyId) { try { $this->authorize('update', $this->application); $this->authorize('useTeamCredentials', $this->application); $key = PrivateKey::where('team_id', $this->application->team()->id)->findOrFail($privateKeyId); $this->privateKeyId = $key->id; $this->syncData(true); $this->getPrivateKeys(); $this->application->refresh(); $this->privateKeyName = $this->application->private_key->name; $this->dispatch('success', 'Private key updated!'); $this->dispatch('configurationChanged'); } catch (\Throwable $e) { return handleError($e, $this); } } public function submit() { try { $this->authorize('update', $this->application); if (str($this->gitCommitSha)->isEmpty()) { $this->gitCommitSha = 'HEAD'; } if (filled($this->gitHttpsUsername) && blank($this->gitHttpsPassword) && ! $this->hasGitHttpsPassword) { throw ValidationException::withMessages(['gitHttpsPassword' => 'Enter the password or token for this username.']); } $this->syncData(true); $this->dispatch('success', 'Application source updated!'); $this->dispatch('configurationChanged'); } catch (\Throwable $e) { return handleError($e, $this); } } public function removeGitHttpsCredential() { try { $this->authorize('update', $this->application); $this->application->forceFill([ 'git_https_username' => null, 'git_https_password' => null, ])->save(); $this->syncData(); $this->dispatch('success', 'HTTPS credentials removed.'); $this->dispatch('configurationChanged'); } catch (\Throwable $e) { return handleError($e, $this); } } public function changeSource($sourceId, $sourceType) { try { $this->authorize('update', $this->application); $this->authorize('useTeamCredentials', $this->application); $allowedSourceTypes = [GithubApp::class, GitlabApp::class, GiteaApp::class]; abort_unless(in_array($sourceType, $allowedSourceTypes, true), 404); $teamId = $this->application->team()->id; $source = $sourceType::query() ->where(fn ($query) => $query->where('team_id', $teamId)->orWhere('is_system_wide', true)) ->findOrFail($sourceId); $this->application->update([ 'source_id' => $source->id, 'source_type' => $sourceType, ]); $this->dispatch('configurationChanged'); ['repository' => $customRepository] = $this->application->customRepository(); $repositorySlug = gitRepositorySlug($customRepository); $repository_project_id = null; if ($sourceType === GithubApp::class) { $repository = githubApi($source, "repos/{$repositorySlug}"); $repository_project_id = data_get($repository, 'data.id'); } elseif ($sourceType === GitlabApp::class) { if ($source->isConnected()) { $encoded = urlencode($repositorySlug); $project = gitlabApi($source, "/projects/{$encoded}"); $repository_project_id = data_get($project, 'data.id'); } } elseif ($sourceType === GiteaApp::class) { if ($source->isConnected()) { $repositoryPath = collect(explode('/', $repositorySlug, 2))->map(fn ($part) => rawurlencode($part))->implode('/'); $repository = giteaApi($source, "/repos/{$repositoryPath}"); $repository_project_id = data_get($repository, 'data.id'); } } if (isset($repository_project_id) && $this->application->repository_project_id !== $repository_project_id) { $this->application->repository_project_id = $repository_project_id; $this->application->save(); } $this->application->refresh(); $this->getSources(); $this->dispatch('success', 'Source updated!'); } catch (\Throwable $e) { return handleError($e, $this); } } }