Class PrivateRepoCloner
java.lang.Object
utu.vbingm.privaterepocloner.PrivateRepoCloner
Facade for storing repo credentials and cloning private HTTPS repositories.
Sensitive data handling: Access tokens are never returned by this API and are never persisted to disk. Tokens are stored in the OS keyring and injected directly into JGit when cloning.
Security note: On most platforms, processes running as the same OS user may access the same keyring. This library mitigates accidental leakage (disk/logs) but cannot defend against malicious code executing under the same user identity. Prefer short-lived tokens and harden the host.
Exceptions
IncorrectTokenForHttpsUrlException
— URL contains credentials or protocol unsupported by HTTPS+token flow.CouldNotReadProfilesJson
— persistent failure to read/repair/writeprofiles.json
.KeyringAccessException
— failure to read/write/delete tokens from the OS keyring.IOException
— network/clone failures raised by JGit (e.g., auth, connectivity, repo not found).
Thread-safety
- Profile-store reads/writes use a JVM-local lock to avoid concurrent file corruption.
- Keyring operations use short-lived handles.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
Immutable DTO for profile metadata (token is never stored here). -
Method Summary
Modifier and TypeMethodDescriptionstatic void
addProfile
(String profileName, String repoUrl, String token) Add or replace a profile and store its access token in the OS keyring.static void
cloneProfileRepo
(String profileName, Path targetDir) Clone a profile's repository totargetDir
using the stored token.static List
<PrivateRepoCloner.PrivateRepo> Returns all stored profile metadata (no tokens).static void
removeProfile
(String profileName) Remove profile metadata and delete its token from the keyring.static boolean
repoExistsInKeyring
(String profileName) Indicates whether a token is present in the keyring for the specified profile.
-
Method Details
-
addProfile
public static void addProfile(String profileName, String repoUrl, String token) throws IncorrectTokenForHttpsUrlException, CouldNotReadProfilesJson, KeyringAccessException Add or replace a profile and store its access token in the OS keyring.Semantics:
- Rejects repository URLs that contain embedded credentials (userinfo component).
- Stores the token first; only if keyring write succeeds does it persist profile metadata.
- Profile
lastUsed
is set to the current epoch millis.
- Parameters:
profileName
- unique profile namerepoUrl
- HTTPS or SSH URL (must not contain credentials)token
- HTTPS token (e.g., GitLab PAT)- Throws:
IncorrectTokenForHttpsUrlException
- ifrepoUrl
contains credentials or is blankCouldNotReadProfilesJson
- if metadata cannot be persisted (after built-in repair)KeyringAccessException
- if the OS keyring rejects the token
-
listProfiles
Returns all stored profile metadata (no tokens).- Returns:
- list of profiles
- Throws:
CouldNotReadProfilesJson
- on persistent store read failure
-
cloneProfileRepo
public static void cloneProfileRepo(String profileName, Path targetDir) throws IncorrectTokenForHttpsUrlException, CouldNotReadProfilesJson, KeyringAccessException, IOException Clone a profile's repository totargetDir
using the stored token. Only HTTPS URLs are supported by this helper (SSH requires separate key-based setup).- Parameters:
profileName
- profile to clonetargetDir
- target directory for the clone- Throws:
IncorrectTokenForHttpsUrlException
- if profile not found, URL has credentials, or URL is non-HTTPSCouldNotReadProfilesJson
- on persistent store read failureKeyringAccessException
- if the token cannot be read from keyringIOException
- if the clone fails (network/auth/repo issues)
-
repoExistsInKeyring
Indicates whether a token is present in the keyring for the specified profile.Returns
false
on keyring lookup failures to avoid leaking backend details.- Parameters:
profileName
- profile to check- Returns:
true
if a (non-empty) token exists, otherwisefalse
-
removeProfile
public static void removeProfile(String profileName) throws CouldNotReadProfilesJson, KeyringAccessException Remove profile metadata and delete its token from the keyring.Semantics:
- Profile removal is idempotent — removing a non-existent profile succeeds.
- Keyring delete is idempotent — on Windows, OS code 1168 ("not found") is treated as no-op.
- Parameters:
profileName
- profile to remove- Throws:
CouldNotReadProfilesJson
- if profile metadata cannot be updatedKeyringAccessException
- if keyring deletion fails with a non-idempotent error
-