Skip to content

Commit

Permalink
Merge branch 'hotfix/2021.1.4' into stable-2021.1
Browse files Browse the repository at this point in the history
  • Loading branch information
PenghaiZhang committed Jan 27, 2022
2 parents 94de657 + 35fb49c commit dad59c0
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.tle.common.security.SecurityConstants
import com.tle.common.security.SecurityConstants.GRANT
import com.tle.core.db.{DB, UserContext}
import com.tle.exceptions.PrivilegeRequiredException
import com.tle.legacy.LegacyGuice
import io.doolse.simpledba.jdbc._

import scala.collection.JavaConverters._
Expand Down Expand Up @@ -107,4 +108,25 @@ object AclChecks {
}
}

/**
* Checks if the current user has the specified ACL.
*
* @param privilege Required ACL, typically defined as a constant in `com.tle.common.security.SecurityConstants`
* @param includePossibleOwnerAcls `true` to include possible owner ACLs
*/
def hasAcl(privilege: String, includePossibleOwnerAcls: Boolean = false): Boolean = {
LegacyGuice.aclManager.hasPrivilege(Set(privilege).asJava, includePossibleOwnerAcls)
}

/**
* Checks if the current user has the specified ACL or throws `PrivilegeRequiredException`.
*
* @param privilege Required ACL, typically defined as a constant in `com.tle.common.security.SecurityConstants`
* @param includePossibleOwnerAcls `true` to include possible owner ACLs
*/
def hasAclOrThrow(privilege: String, includePossibleOwnerAcls: Boolean = false): Unit = {
if (!hasAcl(privilege, includePossibleOwnerAcls)) {
throw new PrivilegeRequiredException(privilege)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ object SearchHelper {
beans.asScala
// Filter out restricted attachments if the user does not have permissions to view them
.filter(a => !a.isRestricted || hasRestrictedAttachmentPrivileges)
.map(sanitiseAttachmentBean)
.map(att => {
val broken =
recurseBrokenAttachmentCheck(
Expand Down Expand Up @@ -317,21 +318,33 @@ object SearchHelper {
}
}

/**
* Find out the latest version of the Item which a Custom Attachment points to.
*
* @param version Version of a linked Item. It is either 0 or 1 where 0 means using the latest version
* and 1 means always using version 1.
* @param uuid UUID of the linked Item.
*/
def getLatestVersionForCustomAttachment(version: Int, uuid: String): Int = {
version match {
// If version of is 0, find the real latest version of this Item.
case 0 => LegacyGuice.itemService.getLatestVersion(uuid)
case realVersion => realVersion
}
}

/**
* Determines if a given customAttachment is invalid. Required as these attachments can be recursive.
* @param customAttachment The attachment to check.
* @return If true, this attachment is broken.
*/
def getBrokenAttachmentStatusForResourceAttachment(
customAttachment: CustomAttachment): Boolean = {
val uuid = customAttachment.getData("uuid").asInstanceOf[String]
// If version of the linked Item is 0, find the latest version of this Item.
val version = customAttachment.getData("version").asInstanceOf[Int] match {
case 0 => LegacyGuice.itemService.getLatestVersion(uuid)
case realVersion => realVersion
}
val uuid = customAttachment.getData("uuid").asInstanceOf[String]
val version = customAttachment.getData("version").asInstanceOf[Int]

val key = new ItemId(uuid, getLatestVersionForCustomAttachment(version, uuid))

val key = new ItemId(uuid, version)
if (customAttachment.getType != "resource") {
return false;
}
Expand Down Expand Up @@ -438,4 +451,23 @@ object SearchHelper {
*/
def isLatestVersion(itemID: ItemIdKey): Boolean =
itemID.getVersion == LegacyGuice.itemService.getLatestVersion(itemID.getUuid)

/**
* When an AttachmentBean is converted to SearchResultAttachment, it may require some extra sanitising
* to complete the conversion. The sanitising work includes tasks listed below.
*
* 1. Help ResourceAttachmentBean check the version of its linked resource.
*
* @param att An AttachmentBean to be sanitised.
*/
def sanitiseAttachmentBean(att: AttachmentBean): AttachmentBean = {
att match {
case bean: ResourceAttachmentBean =>
val latestVersion =
getLatestVersionForCustomAttachment(bean.getItemVersion, bean.getItemUuid)
bean.setItemVersion(latestVersion)
case _ =>
}
att
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ package com.tle.web.api.users
import com.tle.beans.usermanagement.standard.wrapper.SharedSecretSettings
import com.tle.common.security.SecurityConstants
import com.tle.common.usermanagement.user.valuebean.{GroupBean, RoleBean, UserBean}
import com.tle.core.security.AclChecks.hasAclOrThrow
import com.tle.legacy.LegacyGuice
import io.swagger.annotations.{Api, ApiParam}
import javax.ws.rs._

import scala.collection.JavaConverters._

case class LookupQuery(users: Seq[String], groups: Seq[String], roles: Seq[String])
Expand Down Expand Up @@ -55,6 +55,7 @@ class UserQueryResource {
@POST
@Path("lookup")
def lookup(queries: LookupQuery): LookupQueryResult = {
hasAclOrThrow(SecurityConstants.LIST_USERS)
val us = LegacyGuice.userService
val users = us.getInformationForUsers(queries.users.asJava)
val groups = us.getInformationForGroups(queries.groups.asJava)
Expand All @@ -72,6 +73,7 @@ class UserQueryResource {
@QueryParam("groups") @DefaultValue("true") @ApiParam("Include groups") sgroups: Boolean,
@QueryParam("roles") @DefaultValue("true") @ApiParam("Include roles") sroles: Boolean)
: LookupQueryResult = {
hasAclOrThrow(SecurityConstants.LIST_USERS)
val us = LegacyGuice.userService
val users = if (susers) us.searchUsers(q).asScala else Iterable.empty
val groups = if (sgroups) us.searchGroups(q).asScala else Iterable.empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ <T> Collection<T> filterNonGrantedObjects(
*/
boolean hasPrivilege(Object domainObj, Privilege... privilege);

/**
* Check if user has the supplied privileges for any object.
*
* @param privileges List of privileges to be checked
* @param includePossibleOwnerAcls true to include 'ownerAcl'.
* @return true if ANY of the supplied privileges are granted.
*/
boolean hasPrivilege(Collection<String> privileges, boolean includePossibleOwnerAcls);

/** Return a map of domain objects to maps of privileges. */
<T> Map<T, Map<String, Boolean>> getPrivilegesForObjects(
Collection<String> privileges, Collection<T> domainObjs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ public boolean hasPrivilege(Object domainObj, Privilege... privilege) {
return !filterNonGrantedPrivileges(domainObj, privs).isEmpty();
}

@Override
public boolean hasPrivilege(Collection<String> privileges, boolean includePossibleOwnerAcls) {
return !filterNonGrantedPrivileges(privileges, includePossibleOwnerAcls).isEmpty();
}

@Override
@Transactional
public <T> Map<T, Map<String, Boolean>> getPrivilegesForObjects(
Expand Down
13 changes: 13 additions & 0 deletions autotest/Tests/tests/facet/institution/acls/entries.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1910,4 +1910,17 @@
<aclOrder>0</aclOrder>
<aclPriority>-1900</aclPriority>
</com.tle.beans.security.AccessEntry>
<com.tle.beans.security.AccessEntry>
<id>36596</id>
<expression>
<id>36595</id>
<dynamic>false</dynamic>
</expression>
<targetObject>*</targetObject>
<privilege>LIST_USERS</privilege>
<aggregateOrdering>0100 0000 G</aggregateOrdering>
<grantRevoke>G</grantRevoke>
<aclOrder>0</aclOrder>
<aclPriority>-1900</aclPriority>
</com.tle.beans.security.AccessEntry>
</list>
5 changes: 5 additions & 0 deletions autotest/Tests/tests/facet/institution/acls/expressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@
<dynamic>false</dynamic>
<expression>U:f40e91d5-2024-4bb0-87d6-1a0fa22ebae5 </expression>
</com.tle.beans.security.AccessExpression>
<com.tle.beans.security.AccessExpression>
<id>36595</id>
<dynamic>false</dynamic>
<expression>U:f40e91d5-2024-4bb0-87d6-1a0fa22ebae5 R:351c2f38-b78a-4049-88d5-dc33693c9a9f OR </expression>
</com.tle.beans.security.AccessExpression>
</list>
13 changes: 13 additions & 0 deletions autotest/Tests/tests/rest/institution/acls/entries.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1767,4 +1767,17 @@
<aclOrder>1</aclOrder>
<aclPriority>0</aclPriority>
</com.tle.beans.security.AccessEntry>
<com.tle.beans.security.AccessEntry>
<id>37230</id>
<expression>
<id>37229</id>
<dynamic>false</dynamic>
</expression>
<targetObject>*</targetObject>
<privilege>LIST_USERS</privilege>
<aggregateOrdering>0100 0000 G</aggregateOrdering>
<grantRevoke>G</grantRevoke>
<aclOrder>0</aclOrder>
<aclPriority>-1900</aclPriority>
</com.tle.beans.security.AccessEntry>
</list>
5 changes: 5 additions & 0 deletions autotest/Tests/tests/rest/institution/acls/expressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,9 @@
<dynamic>false</dynamic>
<expression>U:adfcaf58-241b-4eca-9740-6a26d1c3dd58 </expression>
</com.tle.beans.security.AccessExpression>
<com.tle.beans.security.AccessExpression>
<id>37229</id>
<dynamic>false</dynamic>
<expression>U:adfcaf58-241b-4eca-9740-6a26d1c3dd58 </expression>
</com.tle.beans.security.AccessExpression>
</list>
15 changes: 14 additions & 1 deletion autotest/Tests/tests/vanilla/institution/acls/entries.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3600,4 +3600,17 @@
<aclOrder>0</aclOrder>
<aclPriority>-1400</aclPriority>
</com.tle.beans.security.AccessEntry>
</list>
<com.tle.beans.security.AccessEntry>
<id>33573</id>
<expression>
<id>33572</id>
<dynamic>false</dynamic>
</expression>
<targetObject>*</targetObject>
<privilege>LIST_USERS</privilege>
<aggregateOrdering>0100 0000 G</aggregateOrdering>
<grantRevoke>G</grantRevoke>
<aclOrder>0</aclOrder>
<aclPriority>-1900</aclPriority>
</com.tle.beans.security.AccessEntry>
</list>
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,9 @@
<dynamic>false</dynamic>
<expression>U:f2ce5cf5-e6d2-8d1a-4627-4e917b4e6ba3</expression>
</com.tle.beans.security.AccessExpression>
</list>
<com.tle.beans.security.AccessExpression>
<id>33572</id>
<dynamic>false</dynamic>
<expression>U:b09a4042-b091-87ed-eba9-6fb3c0fbe9a6 R:ROLE_SYSTEM_ADMINISTRATOR OR </expression>
</com.tle.beans.security.AccessExpression>
</list>
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ name := "Equella"

equellaMajor in ThisBuild := 2021
equellaMinor in ThisBuild := 1
equellaPatch in ThisBuild := 3
equellaPatch in ThisBuild := 4
equellaStream in ThisBuild := "Stable"
equellaBuild in ThisBuild := buildConfig.value.getString("build.buildname")

Expand Down

0 comments on commit dad59c0

Please sign in to comment.