package ca.corefacility.bioinformatics.irida.security.permissions;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import ca.corefacility.bioinformatics.irida.model.joins.Join;
import ca.corefacility.bioinformatics.irida.model.project.Project;
import ca.corefacility.bioinformatics.irida.model.project.ReferenceFile;
import ca.corefacility.bioinformatics.irida.model.user.User;
import ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectReferenceFileJoinRepository;
import ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectUserJoinRepository;
import ca.corefacility.bioinformatics.irida.repositories.referencefile.ReferenceFileRepository;
import ca.corefacility.bioinformatics.irida.repositories.user.UserRepository;

/**
 * Permission testing if a given user can read a given reference file.
 * 
 *
 */
@Component
public class ReadReferenceFilePermission extends BasePermission<ReferenceFile, Long> {

	public static final String PERMISSION_PROVIDED = "canReadReferenceFile";

	private UserRepository userRepository;
	private ProjectUserJoinRepository pujRepository;
	private ProjectReferenceFileJoinRepository prfRepository;

	@Autowired
	public ReadReferenceFilePermission(ReferenceFileRepository referenceFileRepository, UserRepository userRepository,
			ProjectUserJoinRepository pujRepository, ProjectReferenceFileJoinRepository prfRepository) {
		super(ReferenceFile.class, Long.class, referenceFileRepository);
		this.userRepository = userRepository;
		this.pujRepository = pujRepository;
		this.prfRepository = prfRepository;
	}

	@Override
	public String getPermissionProvided() {
		return PERMISSION_PROVIDED;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected boolean customPermissionAllowed(Authentication authentication, ReferenceFile targetDomainObject) {
		// get the logged in user
		User user = userRepository.loadUserByUsername(authentication.getName());
		// get the projects for the file
		List<Join<Project, ReferenceFile>> findProjectsForReferenceFile = prfRepository
				.findProjectsForReferenceFile(targetDomainObject);

		// for each project
		for (Join<Project, ReferenceFile> prJoin : findProjectsForReferenceFile) {
			// get the users on the project
			List<Join<Project, User>> usersForProject = pujRepository.getUsersForProject(prJoin.getSubject());
			for (Join<Project, User> puJoin : usersForProject) {
				// if the user is on the project, they can read the file
				if (puJoin.getObject().equals(user)) {
					return true;
				}
			}
		}

		return false;
	}
}

@@ -505,214 +505,55 @@
 ida.
-model.user.User;%0Aimport ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectReferenceFileJoinRepository;%0Aimport ca.corefacility.bioinformatics.irida.repositories.joins.project.ProjectUser
+repositories.joins.project.ProjectReferenceFile
 Join
@@ -663,86 +663,8 @@
 ory;
-%0Aimport ca.corefacility.bioinformatics.irida.repositories.user.UserRepository;
 %0A%0A/*
@@ -934,87 +934,57 @@
 ate 
-UserRepository userRepository;%0A%09private ProjectUserJoinRepository pujRepository
+final ReadProjectPermission readProjectPermission
 ;%0A%09p
@@ -990,16 +990,22 @@
 private 
+final 
 ProjectR
@@ -1095,16 +1095,22 @@
 mission(
+final 
 Referenc
@@ -1153,54 +1153,38 @@
 ory,
- UserRepository userRepository,%0A%09%09%09ProjectUser
+%0A%09%09%09final ProjectReferenceFile
 Join
@@ -1195,18 +1195,18 @@
 sitory p
-uj
+rf
 Reposito
@@ -1213,56 +1213,57 @@
 ry, 
-ProjectReferenceFileJoinRepository prfRepository
+final ReadProjectPermission readProjectPermission
 ) %7B%0A
@@ -1336,20 +1336,19 @@
 %0A%09%09this.
-user
+prf
 Reposito
@@ -1352,20 +1352,19 @@
 itory = 
-user
+prf
 Reposito
@@ -1378,75 +1378,53 @@
 his.
-pujRepository = pujRepository;%0A%09%09this.prfRepository = prfRepository
+readProjectPermission = readProjectPermission
 ;%0A%09%7D
@@ -1664,111 +1664,8 @@
 ) %7B%0A
-%09%09// get the logged in user%0A%09%09User user = userRepository.loadUserByUsername(authentication.getName());%0A
 %09%09//
@@ -1839,450 +1839,136 @@
 %0A%0A%09%09
-// for each project%0A%09%09for (Join%3CProject, ReferenceFile%3E prJoin : findProjectsForReferenceFile) %7B%0A%09%09%09// get the users on the project%0A%09%09%09List%3CJoin%3CProject, User%3E%3E usersForProject = pujRepository.getUsersForProject(prJoin.getSubject());%0A%09%09%09for (Join%3CProject, User%3E puJoin : usersForProject) %7B%0A%09%09%09%09// if the user is on the project, they can read the file%0A%09%09%09%09if (puJoin
+return findProjectsForReferenceFile.stream()%0A%09%09%09%09.anyMatch(j -%3E readProjectPermission.isAllowed(authentication, j
 .get
-O
+Su
 bject()
-.equals(user)) %7B%0A%09%09%09%09%09return true;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09return false
+))
 ;%0A%09%7D

Rewrite read reference file permission to use project permission.