<commit_before>package com.github.kerubistan.kerub.security


import com.github.kerubistan.kerub.data.AccountMembershipDao
import com.github.kerubistan.kerub.data.AssetDao
import com.github.kerubistan.kerub.data.ControllerConfigDao
import com.github.kerubistan.kerub.data.ProjectmembershipDao
import com.github.kerubistan.kerub.model.Asset
import com.github.kerubistan.kerub.model.AssetOwner
import com.github.kerubistan.kerub.model.AssetOwnerType
import com.github.kerubistan.kerub.model.paging.SearchResultPage
import com.github.kerubistan.kerub.model.paging.SortResultPage
import com.github.kerubistan.kerub.utils.join
import nl.komponents.kovenant.task
import org.apache.shiro.SecurityUtils.getSubject
import java.util.UUID

class AssetAccessControllerImpl(
		private val controllerConfigDao: ControllerConfigDao,
		private val accountMembershipDao: AccountMembershipDao,
		private val projectmembershipDao: ProjectmembershipDao,
		private val validator: Validator
) : AssetAccessController {
	override fun <T : Asset> filter(items: List<T>): List<T> {
		return if (controllerConfigDao.get().accountsRequired) {
			val memberships = memberships(getSubject().principal.toString())
			items.filter {
				item ->
				memberships.any {
					membership ->
					item.owner?.ownerId == membership.ownerId
							&& item.owner?.ownerType == membership.ownerType
				}
			}
		} else {
			items
		}
	}

	override fun <T : Asset> listWithFilter(dao: AssetDao<T>, start: Long, limit: Int, sort: String): SortResultPage<T> {
		return if (filterNotRequired()) {
			val list = dao.list(start, limit, sort)
			SortResultPage(
					start = start,
					count = list.size.toLong(),
					result = list,
					sortBy = sort,
					total = dao.count().toLong()
			)
		} else {
			val owners = memberships(getSubject().principal.toString())
			val list = dao.listByOwners(
					owners = owners,
					limit = limit,
					sort = sort,
					start = start
			)
			SortResultPage(
					start = start,
					count = list.size.toLong(),
					result = list,
					sortBy = sort,
					total = dao.count(owners = owners.toSet()).toLong()
			)
		}
	}

	internal fun memberships(userName: String)
			= listOf(
			task {
				accountMembershipDao.listByUsername(userName).map {
					AssetOwner(ownerId = it.groupId, ownerType = AssetOwnerType.account)
				}
			},
			task {
				projectmembershipDao.listByUsername(userName).map {
					AssetOwner(ownerId = it.groupId, ownerType = AssetOwnerType.project)
				}
			}
	).map { it.get() }.join()


	override fun <T : Asset> searchWithFilter(
			dao: AssetDao<T>,
			field: String,
			value: String,
			start: Long,
			limit: Int
	): SearchResultPage<T> {
		if (filterNotRequired()) {
			val list = dao.fieldSearch(field, value, start, limit)
			return SearchResultPage(
					count = list.size.toLong(),
					result = list,
					searchby = field,
					start = start.toLong(),
					total = dao.count().toLong()
			)
		} else {
			val assetOwners = memberships(getSubject().principal.toString()).toSet()
			val results = dao.fieldSearch(assetOwners, field, value, start, limit)
			return SearchResultPage(
					count = results.size.toLong(),
					result = results,
					searchby = field,
					start = start.toLong(),
					total = results.size.toLong() //TODO
			)
		}
	}

	/**
	 * Filtering of assets not required when the user is an administrator<commit_msg>just cleanup, typo fix<commit_after>package com.github.kerubistan.kerub.security


import com.github.kerubistan.kerub.data.AccountMembershipDao
import com.github.kerubistan.kerub.data.AssetDao
import com.github.kerubistan.kerub.data.ControllerConfigDao
import com.github.kerubistan.kerub.data.ProjectmembershipDao
import com.github.kerubistan.kerub.model.Asset
import com.github.kerubistan.kerub.model.AssetOwner
import com.github.kerubistan.kerub.model.AssetOwnerType
import com.github.kerubistan.kerub.model.paging.SearchResultPage
import com.github.kerubistan.kerub.model.paging.SortResultPage
import com.github.kerubistan.kerub.utils.join
import nl.komponents.kovenant.task
import org.apache.shiro.SecurityUtils.getSubject
import java.util.UUID

class AssetAccessControllerImpl(
		private val controllerConfigDao: ControllerConfigDao,
		private val accountMembershipDao: AccountMembershipDao,
		private val projectMembershipDao: ProjectmembershipDao,
		private val validator: Validator
) : AssetAccessController {
	override fun <T : Asset> filter(items: List<T>): List<T> {
		return if (controllerConfigDao.get().accountsRequired) {
			val memberships = memberships(getSubject().principal.toString())
			items.filter {
				item ->
				memberships.any {
					membership ->
					item.owner?.ownerId == membership.ownerId
							&& item.owner?.ownerType == membership.ownerType
				}
			}
		} else {
			items
		}
	}

	override fun <T : Asset> listWithFilter(dao: AssetDao<T>, start: Long, limit: Int, sort: String): SortResultPage<T> {
		return if (filterNotRequired()) {
			val list = dao.list(start, limit, sort)
			SortResultPage(
					start = start,
					count = list.size.toLong(),
					result = list,
					sortBy = sort,
					total = dao.count().toLong()
			)
		} else {
			val owners = memberships(getSubject().principal.toString())
			val list = dao.listByOwners(
					owners = owners,
					limit = limit,
					sort = sort,
					start = start
			)
			SortResultPage(
					start = start,
					count = list.size.toLong(),
					result = list,
					sortBy = sort,
					total = dao.count(owners = owners.toSet()).toLong()
			)
		}
	}

	internal fun memberships(userName: String)
			= listOf(
			task {
				accountMembershipDao.listByUsername(userName).map {
					AssetOwner(ownerId = it.groupId, ownerType = AssetOwnerType.account)
				}
			},
			task {
				projectMembershipDao.listByUsername(userName).map {
					AssetOwner(ownerId = it.groupId, ownerType = AssetOwnerType.project)
				}
			}
	).map { it.get() }.join()


	override fun <T : Asset> searchWithFilter(
			dao: AssetDao<T>,
			field: String,
			value: String,
			start: Long,
			limit: Int
	): SearchResultPage<T> {
		if (filterNotRequired()) {
			val list = dao.fieldSearch(field, value, start, limit)
			return SearchResultPage(
					count = list.size.toLong(),
					result = list,
					searchby = field,
					start = start,
					total = dao.count().toLong()
			)
		} else {
			val assetOwners = memberships(getSubject().principal.toString()).toSet()
			val results = dao.fieldSearch(assetOwners, field, value, start, limit)
			return SearchResultPage(
					count = results.size.toLong(),
					result = results,
					searchby = field,
					start = start,
					total = results.size.toLong() //TODO
			)
		}
	}

	/**
	 * Filtering of assets not required when the user is an administrator
{'fraction_non_alphanumeric': 0.11471507216188068, 'fraction_numerical': 0.0, 'mean_word_length': 3.566576086956522, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5220750', 'n_tokens_mistral': 2576, 'n_tokens_neox': 2155, 'n_words': 442}