$request->user()->gitConnections ->map(fn (UserGitConnection $gitConnection): array => [ 'account_login' => $gitConnection->account_login, 'account_name' => $gitConnection->account_name, 'base_url' => $gitConnection->base_url, 'created_at' => $gitConnection->created_at?->toISOString(), 'id' => $gitConnection->id, 'provider' => $gitConnection->provider->value, 'provider_label' => $gitConnection->provider->label(), 'provider_user_id' => $gitConnection->provider_user_id, 'updated_at' => $gitConnection->updated_at?->toISOString(), 'user_id' => $gitConnection->user_id, ]) ->values(), 'status' => $request->session()->get('status'), ]); } public function store(StoreUserGitConnectionRequest $request): RedirectResponse { $gitProvider = $this->gitProviderManager->client($request->provider()); try { $gitProvider->verifyRepositoryAccess($request->baseUrl(), $request->apiToken()); } catch (Throwable) { return back() ->withErrors([ 'api_token' => 'KanbanGit could not read repositories from Gitea with this base URL and token.', ]); } $connectionMetadata = $this->resolveConnectionMetadata( $gitProvider, $request->baseUrl(), $request->apiToken(), ); UserGitConnection::query()->create([ ...$connectionMetadata, 'api_token' => $request->apiToken(), 'base_url' => $request->baseUrl(), 'provider' => $request->provider(), 'user_id' => $request->user()->id, ]); return to_route('git-connections.edit') ->with('status', 'Git connection was added.'); } public function update( UpdateUserGitConnectionRequest $request, UserGitConnection $gitConnection, ): RedirectResponse { $this->abortUnlessOwner($request, $gitConnection); $gitProvider = $this->gitProviderManager->client($request->provider()); try { $gitProvider->verifyRepositoryAccess($request->baseUrl(), $request->apiToken()); } catch (Throwable) { return back() ->withErrors([ 'api_token' => 'KanbanGit could not read repositories from Gitea with this base URL and token.', ]); } $connectionMetadata = $this->resolveConnectionMetadata( $gitProvider, $request->baseUrl(), $request->apiToken(), ); $gitConnection->update([ ...$connectionMetadata, 'api_token' => $request->apiToken(), 'base_url' => $request->baseUrl(), 'provider' => $request->provider(), ]); return to_route('git-connections.edit') ->with('status', 'Git connection was updated.'); } public function destroy(Request $request, UserGitConnection $gitConnection): RedirectResponse { $this->abortUnlessOwner($request, $gitConnection); $label = "{$gitConnection->account_login} @ {$gitConnection->base_url}"; $gitConnection->delete(); return to_route('git-connections.edit') ->with('status', "{$label} was removed."); } private function abortUnlessOwner(Request $request, UserGitConnection $gitConnection): void { abort_unless($gitConnection->user_id === $request->user()->id, 403); } /** * @return array{account_login: string, account_name: string|null, provider_user_id: string} */ private function resolveConnectionMetadata( GitProviderClient $gitProvider, string $baseUrl, string $apiToken, ): array { $authenticatedUser = $this->resolveAuthenticatedUser( $gitProvider, $baseUrl, $apiToken, ); return [ 'account_login' => $authenticatedUser?->login ?? $this->fallbackAccountLogin($baseUrl), 'account_name' => $authenticatedUser?->name, 'provider_user_id' => $authenticatedUser?->providerUserId ?? '', ]; } private function resolveAuthenticatedUser( GitProviderClient $gitProvider, string $baseUrl, string $apiToken, ): ?GitAuthenticatedUser { try { return $gitProvider->getAuthenticatedUser($baseUrl, $apiToken); } catch (Throwable) { return null; } } private function fallbackAccountLogin(string $baseUrl): string { $host = parse_url($baseUrl, PHP_URL_HOST); if (is_string($host) && $host !== '') { return Str::lower($host); } return Str::lower($baseUrl); } }