/** * Starts new {@link CandidateSession} for the given {@link User} on the given {@link Delivery} * * <p>NB: No checks are made on whether the {@link User} should be allowed to start a session on * this {@link Delivery}. */ public CandidateSession launchCandidateSession( final User candidate, final Delivery delivery, final boolean authorMode, final String lisOutcomeServiceUrl, final String lisResultSourcedid) throws CandidateException { Assert.notNull(candidate, "candidate"); Assert.notNull(delivery, "delivery"); /* Make sure Candidate's account is not disabled */ if (candidate.isLoginDisabled()) { logAndThrowLaunchException( candidate, delivery, CandidateExceptionReason.USER_ACCOUNT_DISABLED); } /* Make sure Delivery is runnable */ if (delivery.getAssessment() == null) { logAndThrowLaunchException( candidate, delivery, CandidateExceptionReason.LAUNCH_INCOMPLETE_DELIVERY); } /* If the candidate already has any non-terminated sessions open for this Delivery, * then we shall reconnect to the (most recent) session instead of creating a new one. */ final List<CandidateSession> existingSessions = candidateSessionDao.getNonTerminatedForDeliveryAndCandidate(delivery, candidate); if (!existingSessions.isEmpty()) { final CandidateSession mostRecent = existingSessions.get(existingSessions.size() - 1); auditLogger.recordEvent( "Reconnected to existing CandidateSession #" + mostRecent.getId() + " on Delivery #" + delivery.getId()); return mostRecent; } /* No existing session to reconnect to, so create a new session. * * (NB: The session will later need to be explicitly entered before anything can be done * with it.) */ final CandidateSession candidateSession = new CandidateSession(); candidateSession.setLisOutcomeServiceUrl(lisOutcomeServiceUrl); candidateSession.setLisResultSourcedid(lisResultSourcedid); candidateSession.setCandidate(candidate); candidateSession.setDelivery(delivery); candidateSession.setAuthorMode(authorMode); candidateSession.setFinishTime(null); candidateSession.setTerminationTime(null); candidateSession.setExploded(false); candidateSessionDao.persist(candidateSession); auditLogger.recordEvent( "Created and initialised new CandidateSession #" + candidateSession.getId() + " on Delivery #" + delivery.getId()); return candidateSession; }
/** * Check the ACLs for a user doing the passed operation. * * <ul> * <li>If ACLs are disabled, allow all users. * <li>Otherwise, if the operation is not a job operation(for eg. submit-job-to-queue), then * allow only (a) clusterOwner(who started the cluster), (b) cluster administrators and (c) * members of queue-submit-job-acl for the queue. * <li>If the operation is a job operation, then allow only (a) jobOwner, (b) clusterOwner(who * started the cluster), (c) cluster administrators, (d) members of queue admins acl for the * queue and (e) members of job acl for the job operation * </ul> * * @param jobId the job id * @param callerUGI the user who is trying to perform the operation * @param queue the job queue name * @param operation the operation for which authorization is needed * @param jobOwner the user who submitted(or is submitting) this job * @param jobAcl could be job-view-acl or job-modify-acl depending on the job operation. */ void checkAccess( String jobId, UserGroupInformation callerUGI, String queue, Operation operation, String jobOwner, AccessControlList jobAcl) throws AccessControlException { String user = callerUGI.getShortUserName(); String targetResource = jobId + " in queue " + queue; if (!aclsEnabled) { AuditLogger.logSuccess(user, operation.name(), targetResource); return; } // Allow mapreduce cluster admins to do any queue operation and // any job operation if (isMRAdmin(callerUGI)) { AuditLogger.logSuccess(user, operation.name(), targetResource); return; } if (operation == Operation.SUBMIT_JOB) { // This is strictly queue operation(not a job operation) if (!queueManager.hasAccess(queue, operation.qACLNeeded, callerUGI)) { AuditLogger.logFailure( user, operation.name(), queueManager.getQueueACL(queue, operation.qACLNeeded).toString(), targetResource, Constants.UNAUTHORIZED_USER); throw new AccessControlException( "User " + callerUGI.getShortUserName() + " cannot perform " + "operation " + operation.name() + " on queue " + queue + ".\n Please run \"hadoop queue -showacls\" " + "command to find the queues you have access to ."); } else { AuditLogger.logSuccess(user, operation.name(), targetResource); return; } } // Check if callerUGI is queueAdmin(in some cases only), jobOwner or // part of job-acl. // queueManager and queue are null only when called from // TaskTracker(i.e. from TaskLogServlet) for the operation VIEW_TASK_LOGS. // Caller of this method takes care of checking if callerUGI is a // queue administrator for that operation. if (operation == Operation.VIEW_TASK_LOGS) { if (jobACLsManager.checkAccess(callerUGI, operation.jobACLNeeded, jobOwner, jobAcl)) { AuditLogger.logSuccess(user, operation.name(), targetResource); return; } } else if (queueManager.hasAccess(queue, operation.qACLNeeded, callerUGI) || jobACLsManager.checkAccess(callerUGI, operation.jobACLNeeded, jobOwner, jobAcl)) { AuditLogger.logSuccess(user, operation.name(), targetResource); return; } AuditLogger.logFailure( user, operation.name(), jobAcl.toString(), targetResource, Constants.UNAUTHORIZED_USER); throw new AccessControlException( "User " + callerUGI.getShortUserName() + " cannot perform operation " + operation.name() + " on " + jobId + " that is in the queue " + queue); }