Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5.2.5: shares and version history #4771

Merged
merged 12 commits into from Aug 15, 2016
278 changes: 276 additions & 2 deletions components/dsl/resources/ome/dsl/object.vm

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions components/model/resources/mock_filters.hbm.xml
Expand Up @@ -6,4 +6,5 @@
<hibernate-mapping>
<filter-def name="AllGroupsSecurityFilter" condition="1=1"/>
<filter-def name="OneGroupSecurityFilter" condition="1=1"/>
<filter-def name="SharingSecurityFilter" condition="1=1"/>
</hibernate-mapping>
3 changes: 2 additions & 1 deletion components/server/resources/ome/services/hibernate.xml
Expand Up @@ -3,7 +3,7 @@
<!--
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright 2006-2014 University of Dundee. All rights reserved.
# Copyright 2006-2016 University of Dundee. All rights reserved.
# Use is subject to license terms supplied in LICENSE.txt
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -138,6 +138,7 @@
<list>
<ref bean="OneGroupSecurityFilter"/>
<ref bean="AllGroupsSecurityFilter"/>
<ref bean="SharingSecurityFilter"/>
</list>
</property>
<property name="lobHandler" ref="lobHandler"/>
Expand Down
8 changes: 6 additions & 2 deletions components/server/resources/ome/services/indexer.xml
Expand Up @@ -3,8 +3,6 @@
<!--
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# $Id$
#
# Copyright 2009 Glencoe Software, Inc. All rights reserved.
# Use is subject to license terms supplied in LICENSE.txt
#
Expand Down Expand Up @@ -57,6 +55,12 @@
<property name="defaultFilterCondition" value="true"/>
</bean>

<bean id="sharingSecurityFilter" class="ome.security.basic.SharingSecurityFilter">
<constructor-arg ref="roles"/>
<constructor-arg ref="shareStore"/>
<property name="defaultFilterCondition" value="true"/>
</bean>

<bean id="eventListeners" class="ome.security.basic.EventListenersFactoryBean"
depends-on="serverDirectoryCheck">
<constructor-arg ref="currentDetails"/>
Expand Down
8 changes: 6 additions & 2 deletions components/server/resources/ome/services/pixeldata.xml
Expand Up @@ -3,8 +3,6 @@
<!--
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# $Id$
#
# Copyright 2011 Glencoe Software, Inc. All rights reserved.
# Use is subject to license terms supplied in LICENSE.txt
#
Expand Down Expand Up @@ -57,6 +55,12 @@
<property name="defaultFilterCondition" value="true"/>
</bean>

<bean id="sharingSecurityFilter" class="ome.security.basic.SharingSecurityFilter">
<constructor-arg ref="roles"/>
<constructor-arg ref="shareStore"/>
<property name="defaultFilterCondition" value="true"/>
</bean>

<bean id="eventListeners" class="ome.security.basic.EventListenersFactoryBean">
<constructor-arg ref="currentDetails"/>
<constructor-arg ref="tokenHolder"/>
Expand Down
8 changes: 6 additions & 2 deletions components/server/resources/ome/services/sec-primitives.xml
Expand Up @@ -3,8 +3,6 @@
<!--
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# $Id$
#
# Copyright 2008 Glencoe Software, Inc. All rights reserved.
# Use is subject to license terms supplied in LICENSE.txt
#
Expand Down Expand Up @@ -47,6 +45,7 @@
<constructor-arg ref="currentDetails"/>
<constructor-arg ref="&amp;OneGroupSecurityFilter"/><!-- filter is a factory -->
<constructor-arg ref="&amp;AllGroupsSecurityFilter"/><!-- filter is a factory -->
<constructor-arg ref="&amp;SharingSecurityFilter"/><!-- filter is a factory -->
</bean>

<bean id="OneGroupSecurityFilter" class="ome.security.basic.OneGroupSecurityFilter">
Expand All @@ -58,6 +57,11 @@
<constructor-arg ref="roles"/>
</bean>

<bean id="SharingSecurityFilter" class="ome.security.basic.SharingSecurityFilter">
<constructor-arg ref="roles"/>
<constructor-arg ref="shareStore"/>
</bean>

<alias name="${omero.security.chmod_strategy}" alias="chmodStrategy"/>

<bean id="groupChmodStrategy" class="ome.security.basic.GroupChmodStrategy">
Expand Down
15 changes: 12 additions & 3 deletions components/server/src/ome/security/SecurityFilterHolder.java
Expand Up @@ -13,6 +13,7 @@
import ome.security.basic.AllGroupsSecurityFilter;
import ome.security.basic.CurrentDetails;
import ome.security.basic.OneGroupSecurityFilter;
import ome.security.basic.SharingSecurityFilter;
import ome.system.EventContext;

/**
Expand All @@ -29,6 +30,8 @@ public class SecurityFilterHolder implements SecurityFilter {

final protected OneGroupSecurityFilter onegroup;

final protected SharingSecurityFilter share;

final protected CurrentDetails cd;

protected ThreadLocal<SecurityFilter> current = new ThreadLocal<SecurityFilter>() {
Expand All @@ -40,15 +43,21 @@ protected SecurityFilter initialValue() {

public SecurityFilterHolder(CurrentDetails cd,
OneGroupSecurityFilter onegroup,
AllGroupsSecurityFilter allgroups) {
AllGroupsSecurityFilter allgroups,
SharingSecurityFilter share) {
this.cd = cd;
this.onegroup = onegroup;
this.allgroups = allgroups;
this.share = share;
}

public SecurityFilter choose() {
Long groupId = cd.getCurrentEventContext().getCurrentGroupId();
if (groupId < 0) {
final EventContext ec = cd.getCurrentEventContext();
final Long groupId = ec.getCurrentGroupId();
final Long shareId = ec.getCurrentShareId();
if (shareId != null && shareId >= 0) {
return share;
} else if (groupId < 0) {
return allgroups;
} else {
return onegroup;
Expand Down
Expand Up @@ -126,7 +126,8 @@ public static BasicSecuritySystem selfConfigure(SessionManager sm,
Roles roles = new Roles();
SecurityFilterHolder holder = new SecurityFilterHolder(
cd, new OneGroupSecurityFilter(roles),
new AllGroupsSecurityFilter(null, roles));
new AllGroupsSecurityFilter(null, roles),
new SharingSecurityFilter(roles, null));
BasicSecuritySystem sec = new BasicSecuritySystem(oi, st, cd, sm,
roles, sf, new TokenHolder(), holder, new DefaultPolicyService());
return sec;
Expand Down
20 changes: 11 additions & 9 deletions components/server/src/ome/security/basic/OmeroInterceptor.java
Expand Up @@ -708,7 +708,7 @@ else if ((bec.getCurrentGroupId() < 0) &&
}

// EXTERNALINFO
// useres _are_ allowed to set the external info on a new object.
// users _are_ allowed to set the external info on a new object.
// subsequent operations, however, will not be able to edit this
// value.
newDetails.setExternalInfo(source.getExternalInfo());
Expand Down Expand Up @@ -818,10 +818,9 @@ else if (currentDetails == null) {
// the object doesn't have owner/group
final boolean sysType = sysTypes.isSystemType(iobj.getClass());

// isGlobal implies nothing (currently) about external info
// see mapping.vm for more.
altered |= managedExternalInfo(privileged, iobj,
previousDetails, currentDetails, newDetails);
// As of 5.2, we are no longer being restrictive about external
// info. It is now a user-concern and can be changed like other
// fields.

// implies that owner doesn't matter
if (!sysType) {
Expand Down Expand Up @@ -858,7 +857,8 @@ else if (currentDetails == null) {

/**
* responsible for guaranteeing that external info is not modified by any
* users, including root.
* users, including root. This does not apply to the "client concern" fields
* which can be modified after the fact.
*
* @param privileged if the user is privileged
* @param obj the model object
Expand All @@ -871,6 +871,7 @@ else if (currentDetails == null) {
* {@link Permissions}
* @return true if the {@link Permissions} of newDetails are changed.
*/
@Deprecated
protected boolean managedExternalInfo(boolean privileged,
IObject obj, Details previousDetails, Details currentDetails,
Details newDetails) {
Expand All @@ -884,9 +885,10 @@ protected boolean managedExternalInfo(boolean privileged,
.getExternalInfo();

if (previous == null) {
// do we allow a change?
newDetails.setExternalInfo(current);
altered |= newDetails.getExternalInfo() != current;
if (current != null) {
newDetails.setExternalInfo(current);
altered = true;
}
}

// The ExternalInfo was previously set. We do not allow it to be
Expand Down
107 changes: 107 additions & 0 deletions components/server/src/ome/security/basic/SharingSecurityFilter.java
@@ -0,0 +1,107 @@
/*
* Copyright (C) 2016 University of Dundee & Open Microscopy Environment.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package ome.security.basic;

import java.util.List;
import java.util.Map;

import ome.model.core.Image;
import ome.model.internal.Details;
import ome.services.sharing.ShareStore;
import ome.services.sharing.data.ShareData;
import ome.system.EventContext;
import ome.system.Roles;

import org.apache.commons.collections.CollectionUtils;
import org.hibernate.Filter;
import org.hibernate.Session;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

/**
* The sharing security filter provides database-level access protection for share contexts.
* @see ome.security.sharing.SharingACLVoter
* @author m.t.b.carroll@dundee.ac.uk
* @since 5.2.5
*/
public class SharingSecurityFilter extends AbstractSecurityFilter {

private static final ImmutableMap<String, String> PARAMETER_TYPES =
ImmutableMap.of("is_admin", "int",
"is_share", "int",
"images", "long");

private ShareStore shares;

/**
* Construct a new sharing security filter.
* @param roles the users and groups that are special to OMERO
* @param shares the shares
*/
public SharingSecurityFilter(Roles roles, ShareStore shares) {
super(roles);
this.shares = shares;
}

@Override
public Map<String, String> getParameterTypes() {
return PARAMETER_TYPES;
}

@Override
public String getDefaultCondition() {
/* provided instead by annotations */
return null;
}

@Override
public boolean passesFilter(Session session, Details details, EventContext ec) {
final Long shareId = ec.getCurrentShareId();
if (shareId == null) {
return true;
}
final ShareData share = shares.get(shareId);
return ec.isCurrentUserAdmin() || share != null && share.enabled;
}

@Override
public void enable(Session session, EventContext ec) {
List<Long> imageIds = null;
final Long shareId = ec.getCurrentShareId();
if (shareId != null) {
final ShareData shareData = shares.get(shareId);
if (shareData != null && shareData.enabled) {
imageIds = shareData.objectMap.get(Image.class.getName());
}
}
if (CollectionUtils.isEmpty(imageIds)) {
imageIds = ImmutableList.of(-1L);
}
final int isAdmin01 = ec.isCurrentUserAdmin() ? 1 : 0;
final int isShare01 = isShare(ec) ? 1 : 0;

final Filter filter = session.enableFilter(getName());
filter.setParameter("is_admin", isAdmin01);
filter.setParameter("is_share", isShare01);
filter.setParameterList("images", imageIds);
enableBaseFilters(session, isAdmin01, ec.getCurrentUserId());
}
}
1 change: 1 addition & 0 deletions components/tools/OmeroPy/test/integration/test_ishare.py
Expand Up @@ -278,6 +278,7 @@ def test1157(self):
c2 = len(share2.getComments(sid))
assert 2 == c2

@pytest.mark.broken(reason="shares are image-centric for now")
def test1172(self):
uuid = self.root.sf.getAdminService().getEventContext().sessionUuid
share = self.root.sf.getShareService()
Expand Down