Skip to content

Commit

Permalink
add commithash to log
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonEntholzer committed Aug 20, 2024
1 parent b0e1d72 commit ea9e1e8
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,8 @@ public VcsAccessLog(User user, Participation participation, String name, String

public VcsAccessLog() {
}

public void setCommitHash(String commitHash) {
this.commitHash = commitHash;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import static de.tum.in.www1.artemis.config.Constants.PROFILE_CORE;

import java.util.Optional;

import org.springframework.context.annotation.Profile;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import de.tum.in.www1.artemis.domain.vcstokens.VcsAccessLog;
Expand All @@ -20,4 +24,18 @@
@Repository
public interface VcsAccessLogRepository extends ArtemisJpaRepository<VcsAccessLog, Long> {

/**
* Find the access log entry which does not have any commit hash yet
*
* @param participationId Current time
* @return a log entry belonging with the participationId, which has no commit hash
*/
@Query("""
SELECT vcsAccessLog
FROM VcsAccessLog vcsAccessLog
WHERE vcsAccessLog.participation.id = :participationId
AND vcsAccessLog.commitHash IS NULL
""")
Optional<VcsAccessLog> findByParticipationIdWhereCommitHashIsNull(@Param("participationId") long participationId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,27 @@ public class VcsAccessLogService {
* @param user The user accessing the repository
* @param participation The participation which owns the repository
* @param actionType The action type: READ or WRITE
* @param authenticationMechanism The used authentication mechanism: password, token or SSH
* @param authenticationMechanism The used authentication mechanism: password, vcs token (user/participation) or SSH
*/
public void storeAccessLog(User user, ProgrammingExerciseParticipation participation, RepositoryActionType actionType, AuthenticationMechanism authenticationMechanism,
String ipAddress) {
String commitHash, String ipAddress) {
log.debug("Storing access operation for user {}", user);

VcsAccessLog accessLogEntry = new VcsAccessLog(user, (Participation) participation, user.getName(), user.getEmail(), actionType, authenticationMechanism, null, ipAddress);
VcsAccessLog accessLogEntry = new VcsAccessLog(user, (Participation) participation, user.getName(), user.getEmail(), actionType, authenticationMechanism, commitHash,
ipAddress);
vcsAccessLogRepository.save(accessLogEntry);
}

/**
* Updates the commit hash after a successful push
*
* @param participation The participation to which the repository belongs to
* @param commitHash The newest commit hash which should get set for the access log entry
*/
public void updateCommitHash(ProgrammingExerciseParticipation participation, String commitHash) {
vcsAccessLogRepository.findByParticipationIdWhereCommitHashIsNull(participation.getId()).ifPresent(entry -> {
entry.setCommitHash(commitHash);
vcsAccessLogRepository.save(entry);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public void authenticateAndAuthorizeGitRequest(HttpServletRequest request, Repos

var authenticationMechanism = resolveAuthenticationMechanism(authorizationHeader, user);
var ipAddress = request.getRemoteAddr();
authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, authenticationMechanism, ipAddress, localVCRepositoryUri.isPracticeRepository());
authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, authenticationMechanism, ipAddress, localVCRepositoryUri);

request.setAttribute("user", user);

Expand Down Expand Up @@ -407,11 +407,11 @@ private UsernameAndPassword extractUsernameAndPassword(String authorizationHeade
* @param user The user that wants to access the repository.
* @param exercise The exercise the repository belongs to.
* @param repositoryActionType The type of the action the user wants to perform.
* @param isPracticeRepository Whether the repository is a practice repository.
* @param localVCRepositoryUri The URI of the local repository.
* @throws LocalVCForbiddenException If the user is not allowed to access the repository.
*/
public void authorizeUser(String repositoryTypeOrUserName, User user, ProgrammingExercise exercise, RepositoryActionType repositoryActionType,
AuthenticationMechanism authenticationMechanism, String ipAddress, boolean isPracticeRepository) throws LocalVCForbiddenException {
AuthenticationMechanism authenticationMechanism, String ipAddress, LocalVCRepositoryUri localVCRepositoryUri) throws LocalVCForbiddenException {

if (repositoryTypeOrUserName.equals(RepositoryType.TESTS.toString()) || auxiliaryRepositoryService.isAuxiliaryRepositoryOfExercise(repositoryTypeOrUserName, exercise)) {
// Test and auxiliary repositories are only accessible by instructors and higher.
Expand All @@ -426,7 +426,8 @@ public void authorizeUser(String repositoryTypeOrUserName, User user, Programmin

ProgrammingExerciseParticipation participation;
try {
participation = programmingExerciseParticipationService.getParticipationForRepository(exercise, repositoryTypeOrUserName, isPracticeRepository, false);
participation = programmingExerciseParticipationService.getParticipationForRepository(exercise, repositoryTypeOrUserName, localVCRepositoryUri.isPracticeRepository(),
false);
}
catch (EntityNotFoundException e) {
throw new LocalVCInternalException(
Expand All @@ -435,11 +436,22 @@ public void authorizeUser(String repositoryTypeOrUserName, User user, Programmin

try {
repositoryAccessService.checkAccessRepositoryElseThrow(participation, user, exercise, repositoryActionType);
vcsAccessLogService.storeAccessLog(user, participation, repositoryActionType, authenticationMechanism, ipAddress);
}
catch (AccessForbiddenException e) {
throw new LocalVCForbiddenException(e);
}
String commitHash = null;
try {
if (repositoryActionType == RepositoryActionType.READ) {
commitHash = getLatestCommitHash(repositories.get(localVCRepositoryUri.getRelativeRepositoryPath().toString()));
}
}
catch (GitAPIException e) {
log.warn("Failed to obtain commit hash for repository {}. Error: {}", localVCRepositoryUri.getRelativeRepositoryPath().toString(), e.getMessage());
}
// Write a access log entry to the database
vcsAccessLogService.storeAccessLog(user, participation, repositoryActionType, authenticationMechanism, commitHash, ipAddress);

}

/**
Expand Down Expand Up @@ -506,6 +518,9 @@ public void processNewPush(String commitHash, Repository repository) {

// Process push to any repository other than the test repository.
processNewPushToRepository(participation, commit);

// For push the correct commitHash is only available here, therefore the preliminary null value is overwritten
vcsAccessLogService.updateCommitHash(participation, commitHash);
}
catch (GitAPIException | IOException e) {
// This catch clause does not catch exceptions that happen during runBuildJob() as that method is called asynchronously.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public Path resolveRootDirectory(String command, String[] args, ServerSession se
final var user = session.getAttribute(SshConstants.USER_KEY);
try {
localVCServletService.authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, AuthenticationMechanism.SSH, session.getClientAddress().toString(),
localVCRepositoryUri.isPracticeRepository());
localVCRepositoryUri);
}
catch (LocalVCForbiddenException e) {
log.error("User {} does not have access to the repository {}", user.getLogin(), repositoryPath);
Expand Down

0 comments on commit ea9e1e8

Please sign in to comment.