Package ome.security.basic
Class BasicSecuritySystem
- java.lang.Object
-
- ome.security.basic.BasicSecuritySystem
-
- All Implemented Interfaces:
java.util.EventListener
,SecuritySystem
,org.springframework.beans.factory.Aware
,org.springframework.context.ApplicationContextAware
,org.springframework.context.ApplicationListener<EventLogMessage>
- Direct Known Subclasses:
BasicSecuritySystemReadOnly
public class BasicSecuritySystem extends java.lang.Object implements SecuritySystem, org.springframework.context.ApplicationContextAware, org.springframework.context.ApplicationListener<EventLogMessage>
simplest implementation ofSecuritySystem
. Uses an ctor-injectedEventContext
and theThreadLocal-
basedCurrentDetails
to provide the security infrastructure.- Since:
- 3.0-M3
- See Also:
Token
,SecuritySystem
,Details
,Permissions
-
-
Field Summary
Fields Modifier and Type Field Description protected ACLVoter
aclVoter
protected CurrentDetails
cd
protected ome.system.OmeroContext
ctx
protected EventProvider
eventProvider
protected java.util.List<SecurityFilter>
filters
protected OmeroInterceptor
interceptor
protected PolicyService
policyService
protected ome.system.Roles
roles
protected SessionManager
sessionManager
protected SessionProvider
sessionProvider
protected ome.system.ServiceFactory
sf
protected ShareStore
store
protected SystemTypes
sysTypes
protected TokenHolder
tokenHolder
-
Constructor Summary
Constructors Constructor Description BasicSecuritySystem(OmeroInterceptor interceptor, SystemTypes sysTypes, CurrentDetails cd, SessionManager sessionManager, SessionProvider sessionProvider, EventProvider eventProvider, ome.system.Roles roles, ome.system.ServiceFactory sf, TokenHolder tokenHolder, java.util.List<SecurityFilter> filters, PolicyService policyService, ACLVoter aclVoter)
Main public constructor for thisSecuritySystem
implementation.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addLog(java.lang.String action, java.lang.Class klass, java.lang.Long id)
ome.model.internal.Details
checkManagedDetails(ome.model.IObject object, ome.model.internal.Details trustedDetails)
checks that a non-privileged user has not attempted to edit the entity'ssecurity details
.protected void
checkReady(java.lang.String method)
callsisReady()
and if not throws anApiUsageException
.void
checkRestriction(java.lang.String name, ome.model.IObject obj)
Checks whether or not aPolicy
instance of matching name has been registered, considers itself active, and considers the passed context object to be restricted.void
clearLogs()
void
copyToken(ome.model.IObject source, ome.model.IObject copy)
void
disable(java.lang.String... ids)
disables components of the backend for the current Thread.void
disableReadFilter(java.lang.Object session)
disable this filer.<T extends ome.model.IObject>
TdoAction(SecureAction action, T... objs)
It would be better to catch theSecureAction.updateObject(IObject...)
method in a try/finally block, but since flush can be so poorly controlled that's not possible.void
enable(java.lang.String... ids)
enables components of the backend for the current Thread.void
enableReadFilter(java.lang.Object session)
enables the read filter such that graph queries will have non-visible entities silently removed from the return value.java.lang.Long
getEffectiveUID()
Returns the Id of the currently logged in user.ome.system.EventContext
getEventContext()
CallsSecuritySystem.getEventContext(boolean)
with a false as "refresh".ome.system.EventContext
getEventContext(boolean refresh)
If refresh is false, returns the currentEventContext
stored in the session.java.util.List<ome.model.meta.EventLog>
getLogs()
ome.system.Roles
getSecurityRoles()
boolean
hasPrivilegedToken(ome.model.IObject obj)
void
invalidateEventContext()
Clears the content of theEventContext
so that theSecuritySystem
will no longer return true forSecuritySystem.isReady()
.boolean
isDisabled(java.lang.String id)
checks if the listed id is disabled for the current Thread.boolean
isGraphCritical(ome.model.internal.Details details)
Determines if the current security context has the possibility of corrupting consistent graphs.protected boolean
isGroupContextPermitted(long sessionId, long groupId)
Check the given group context.protected boolean
isGroupContextPermitted(long groupId, java.lang.String permittedGroupIds)
boolean
isOwnerOrSupervisor(ome.model.IObject iObject)
tests whether or not the current user is either the owner of this entity, or the supervisor of this entity, for example as root or as group owner.boolean
isReady()
implementsSecuritySystem.isReady()
.boolean
isSystemType(java.lang.Class<? extends ome.model.IObject> klass)
classes which cannot be created by regular users.void
loadEventContext(boolean isReadOnly)
Prepares the currentEventContext
instance with the currentPrincipal
.void
loadEventContext(boolean isReadOnly, boolean isClose)
void
login(ome.system.Principal principal)
stores thisPrincipal
instance in the current thread context for authenticating and authorizing all actions.int
logout()
clears the topPrincipal
instance from the current thread context.ome.model.internal.Details
newTransientDetails(ome.model.IObject object)
creates a new securedetails
for transient entities.void
onApplicationEvent(EventLogMessage elm)
void
runAsAdmin(ome.model.meta.ExperimenterGroup group, AdminAction action)
merge event is disabled forrunAsAdmin(AdminAction)
because passing detached (client-side) entities to this method is particularly dangerous.void
runAsAdmin(AdminAction action)
CallsrunAsAdmin(AdminAction)
with a null-group id.static BasicSecuritySystem
selfConfigure(SessionManager sm, ome.system.ServiceFactory sf, SessionCache cache)
Simplified factory method which generates all the security primitives internally.void
setApplicationContext(org.springframework.context.ApplicationContext arg0)
void
updateReadFilter(org.hibernate.Session session)
-
-
-
Field Detail
-
interceptor
protected final OmeroInterceptor interceptor
-
sysTypes
protected final SystemTypes sysTypes
-
cd
protected final CurrentDetails cd
-
tokenHolder
protected final TokenHolder tokenHolder
-
roles
protected final ome.system.Roles roles
-
sessionManager
protected final SessionManager sessionManager
-
sessionProvider
protected final SessionProvider sessionProvider
-
eventProvider
protected final EventProvider eventProvider
-
sf
protected final ome.system.ServiceFactory sf
-
filters
protected final java.util.List<SecurityFilter> filters
-
policyService
protected final PolicyService policyService
-
ctx
protected ome.system.OmeroContext ctx
-
store
protected ShareStore store
-
aclVoter
protected final ACLVoter aclVoter
-
-
Constructor Detail
-
BasicSecuritySystem
public BasicSecuritySystem(OmeroInterceptor interceptor, SystemTypes sysTypes, CurrentDetails cd, SessionManager sessionManager, SessionProvider sessionProvider, EventProvider eventProvider, ome.system.Roles roles, ome.system.ServiceFactory sf, TokenHolder tokenHolder, java.util.List<SecurityFilter> filters, PolicyService policyService, ACLVoter aclVoter)
Main public constructor for thisSecuritySystem
implementation.- Parameters:
interceptor
- the OMERO interceptor for HibernatesysTypes
- the system typescd
- the current detailssessionManager
- the session managersessionProvider
- a session providereventProvider
- an event providerroles
- the OMERO rolessf
- the session factorytokenHolder
- the token holderfilters
- the security filterspolicyService
- the policy serviceaclVoter
- the ACL voter, may benull
-
-
Method Detail
-
selfConfigure
public static BasicSecuritySystem selfConfigure(SessionManager sm, ome.system.ServiceFactory sf, SessionCache cache)
Simplified factory method which generates all the security primitives internally. Primarily useful for generated testing instances.- Parameters:
sm
- the session managersf
- the session factorycache
- the session cache- Returns:
- a configured security system
-
setApplicationContext
public void setApplicationContext(org.springframework.context.ApplicationContext arg0) throws org.springframework.beans.BeansException
- Specified by:
setApplicationContext
in interfaceorg.springframework.context.ApplicationContextAware
- Throws:
org.springframework.beans.BeansException
-
login
public void login(ome.system.Principal principal)
Description copied from interface:SecuritySystem
stores thisPrincipal
instance in the current thread context for authenticating and authorizing all actions. This method does not make any queries and is only a conduit for login information from the outermost levels. Session bean implementations and other in-JVM clients can fill thePrincipal
. Note, however, a call must first be made toSecuritySystem.loadEventContext(boolean)
for some calls to be made to theSecuritySystem
. In general, this means that execution must pass through theEventHandler
- Specified by:
login
in interfaceSecuritySystem
- Parameters:
principal
- the new current principal
-
logout
public int logout()
Description copied from interface:SecuritySystem
clears the topPrincipal
instance from the current thread context.- Specified by:
logout
in interfaceSecuritySystem
- Returns:
- the number of remaining instances.
-
isReady
public boolean isReady()
implementsSecuritySystem.isReady()
. Simply checks for null values in all the relevant fields ofCurrentDetails
- Specified by:
isReady
in interfaceSecuritySystem
- Returns:
- true if all methods on this interface are ready to be called.
-
isSystemType
public boolean isSystemType(java.lang.Class<? extends ome.model.IObject> klass)
classes which cannot be created by regular users.- Specified by:
isSystemType
in interfaceSecuritySystem
- Parameters:
klass
- A class which extends fromIObject
- Returns:
- true if instances of the class argument can be considered system types.
- See Also:
- ticket156
-
isOwnerOrSupervisor
public boolean isOwnerOrSupervisor(ome.model.IObject iObject)
tests whether or not the current user is either the owner of this entity, or the supervisor of this entity, for example as root or as group owner.- Parameters:
iObject
- Non-null managed entity.- Returns:
- true if the current user is owner or supervisor of this entity
-
enableReadFilter
public void enableReadFilter(java.lang.Object session)
enables the read filter such that graph queries will have non-visible entities silently removed from the return value. This filter does not apply to single value loads from the database. SeeACLVoter.allowLoad(Session, Class, Details, long)
for more. Note: this filter must be disabled on logout, otherwise the necessary parameters (current user, current group, etc.) for building the filters will not be available. Similarly, while enabling this filter, no calls should be made on the given session object.- Parameters:
session
- a generic session object which can be used to enable this filter. EachSecuritySystem
implementation will require a specific session type.- See Also:
EventHandler.invoke(org.aopalliance.intercept.MethodInvocation)
-
updateReadFilter
public void updateReadFilter(org.hibernate.Session session)
-
disableReadFilter
public void disableReadFilter(java.lang.Object session)
disable this filer. All future queries will have no security context associated with them and all items will be visible.- Parameters:
session
- a generic session object which can be used to disable this filter. EachSecuritySystem
implementation will require a specifc session type.- See Also:
EventHandler.invoke(org.aopalliance.intercept.MethodInvocation)
-
disable
public void disable(java.lang.String... ids)
Description copied from interface:SecuritySystem
disables components of the backend for the current Thread. Further checks toSecuritySystem.isDisabled(String)
will return false. It is the responsibility of various security system components to then throw exceptions.- Specified by:
disable
in interfaceSecuritySystem
- Parameters:
ids
- Non-null, non-empty array of String ids to disable.
-
enable
public void enable(java.lang.String... ids)
Description copied from interface:SecuritySystem
enables components of the backend for the current Thread. Further checks toSecuritySystem.isDisabled(String)
will return true.- Specified by:
enable
in interfaceSecuritySystem
- Parameters:
ids
- possibly null array of String ids. A null array specifies that all subsystems are to be enabled. Otherwise, only those subsystems specified by the ids.
-
isDisabled
public boolean isDisabled(java.lang.String id)
Description copied from interface:SecuritySystem
checks if the listed id is disabled for the current Thread.- Specified by:
isDisabled
in interfaceSecuritySystem
- Parameters:
id
- non-null String representing a backend subsystem.- Returns:
- true if the backend subsystem has been previously disabled by
calls to
SecuritySystem.disable(String[])
-
newTransientDetails
public ome.model.internal.Details newTransientDetails(ome.model.IObject object) throws ome.conditions.ApiUsageException, ome.conditions.SecurityViolation
Description copied from interface:SecuritySystem
creates a new securedetails
for transient entities. Non-privileged users can only edit thePermissions
field. Privileged users can use theDetails
object as a single-stepchmod
andchgrp
.newTransientDetails
always returns a non-null Details that is not equivalent (==) to the Details argument. This method can be used from anywhere in the codebase to obtain a validDetails
, but passing in anIObject
instance with a nullDetails
. However, if theDetails
is non-null, there is the possibility that this method will throw an exception.- Specified by:
newTransientDetails
in interfaceSecuritySystem
- Throws:
ome.conditions.ApiUsageException
- ifSecuritySystem
is notready
ome.conditions.SecurityViolation
- ifDetails
instance contains illegal values.
-
checkManagedDetails
public ome.model.internal.Details checkManagedDetails(ome.model.IObject object, ome.model.internal.Details trustedDetails) throws ome.conditions.ApiUsageException, ome.conditions.SecurityViolation
Description copied from interface:SecuritySystem
checks that a non-privileged user has not attempted to edit the entity'ssecurity details
. Privileged users can set fields onDetails
as a single-stepchmod
andchgrp
.managedDetails
may create a new Details instance and return that if needed. If the returned Details is not equivalent (==) to the argument Details, then values have been changed.- Specified by:
checkManagedDetails
in interfaceSecuritySystem
- Parameters:
object
- non-nullIObject
instance.Details
for that instance can be null.trustedDetails
- possibly nullDetails
instance. TheseDetails
are trusted in the sense that they have already once passed through theSecuritySystem
.- Throws:
ome.conditions.ApiUsageException
- ifSecuritySystem
is notready
ome.conditions.SecurityViolation
- ifDetails
instance contains illegal values.
-
isGraphCritical
public boolean isGraphCritical(ome.model.internal.Details details)
Description copied from interface:SecuritySystem
Determines if the current security context has the possibility of corrupting consistent graphs. Consistent graphs are enforced by the security context to make sure that all READ actions work smoothly. If an administrator or PI is logged into a private group, or otherwise may create an object linked to an object with lower READ rights, then corruption could occur. Starting with 4.4.2, a trusted details object should be passed in order to handle the situation where the current group id is -1. Possibles cases that can occur:The current group is non-negative, then use the previous logic; else the current group is negative, and the object is in a non-"user" group: USE THAT GROUP; else the object is in the "user" group: UNCLEAR (for the moment we're throwing an exception)
If noDetails
instance is passed or aDetails
without aExperimenterGroup
value, then throw as well.- Specified by:
isGraphCritical
in interfaceSecuritySystem
- Parameters:
details
- the details- Returns:
- if the graph is critical
- See Also:
- 1769,
-
isGroupContextPermitted
protected boolean isGroupContextPermitted(long sessionId, long groupId)
Check the given group context.- Parameters:
sessionId
- a session IDgroupId
- a group ID- Returns:
- if the group context is permitted for the given session
-
isGroupContextPermitted
protected boolean isGroupContextPermitted(long groupId, java.lang.String permittedGroupIds)
- Parameters:
groupId
- a group IDpermittedGroupIds
- a comma-separated string of group IDs- Returns:
- if the string of IDs contains the given group
-
loadEventContext
public void loadEventContext(boolean isReadOnly)
Description copied from interface:SecuritySystem
Prepares the currentEventContext
instance with the currentPrincipal
. An exception is thrown if there is none.- Specified by:
loadEventContext
in interfaceSecuritySystem
-
loadEventContext
public void loadEventContext(boolean isReadOnly, boolean isClose)
-
addLog
public void addLog(java.lang.String action, java.lang.Class klass, java.lang.Long id)
-
getLogs
public java.util.List<ome.model.meta.EventLog> getLogs()
-
clearLogs
public void clearLogs()
-
invalidateEventContext
public void invalidateEventContext()
Description copied from interface:SecuritySystem
Clears the content of theEventContext
so that theSecuritySystem
will no longer return true forSecuritySystem.isReady()
. ThePrincipal
set duringSecuritySystem.login(Principal)
is retained.- Specified by:
invalidateEventContext
in interfaceSecuritySystem
-
doAction
public <T extends ome.model.IObject> T doAction(SecureAction action, T... objs)
It would be better to catch theSecureAction.updateObject(IObject...)
method in a try/finally block, but since flush can be so poorly controlled that's not possible. instead, we use the one time token which is removed this Object is checked forprivileges
.- Specified by:
doAction
in interfaceSecuritySystem
- Parameters:
objs
- A managed (non-detached) entity. Not null.action
- A code-block that will be given the entity argument with ahasPrivilegedToken(IObject)
privileged token}.
-
runAsAdmin
public void runAsAdmin(AdminAction action)
CallsrunAsAdmin(AdminAction)
with a null-group id.- Specified by:
runAsAdmin
in interfaceSecuritySystem
- Parameters:
action
- the action to run
-
runAsAdmin
public void runAsAdmin(ome.model.meta.ExperimenterGroup group, AdminAction action)
merge event is disabled forrunAsAdmin(AdminAction)
because passing detached (client-side) entities to this method is particularly dangerous.- Specified by:
runAsAdmin
in interfaceSecuritySystem
- Parameters:
group
- the group to run the action asaction
- the action to run
-
copyToken
public void copyToken(ome.model.IObject source, ome.model.IObject copy)
- See Also:
TokenHolder.copyToken(IObject, IObject)
-
hasPrivilegedToken
public boolean hasPrivilegedToken(ome.model.IObject obj)
Description copied from interface:SecuritySystem
- Specified by:
hasPrivilegedToken
in interfaceSecuritySystem
- See Also:
TokenHolder.hasPrivilegedToken(IObject)
-
checkRestriction
public void checkRestriction(java.lang.String name, ome.model.IObject obj)
Description copied from interface:SecuritySystem
Checks whether or not aPolicy
instance of matching name has been registered, considers itself active, and considers the passed context object to be restricted.- Specified by:
checkRestriction
in interfaceSecuritySystem
- Parameters:
name
- A non-null unique name for a class of policies.obj
- An instance which is to be checked against matching policies.
-
getSecurityRoles
public ome.system.Roles getSecurityRoles()
- Specified by:
getSecurityRoles
in interfaceSecuritySystem
-
getEventContext
public ome.system.EventContext getEventContext(boolean refresh)
Description copied from interface:SecuritySystem
If refresh is false, returns the currentEventContext
stored in the session. Otherwise, reloads the context to have the most up-to-date information.- Specified by:
getEventContext
in interfaceSecuritySystem
- Parameters:
refresh
- if the event context should first be reloaded- Returns:
- the event context
- See Also:
- Trac ticket #4011
-
getEventContext
public ome.system.EventContext getEventContext()
Description copied from interface:SecuritySystem
CallsSecuritySystem.getEventContext(boolean)
with a false as "refresh". This is the previous, safer logic of the method since consumers are not expecting a long method run.- Specified by:
getEventContext
in interfaceSecuritySystem
- Returns:
- the event context
-
getEffectiveUID
public java.lang.Long getEffectiveUID()
Returns the Id of the currently logged in user. Returns owner of the share while in share- Specified by:
getEffectiveUID
in interfaceSecuritySystem
- Returns:
- See above.
-
checkReady
protected void checkReady(java.lang.String method)
callsisReady()
and if not throws anApiUsageException
. TheSecuritySystem
must be in a valid state to perform several functions.
-
onApplicationEvent
public void onApplicationEvent(EventLogMessage elm)
- Specified by:
onApplicationEvent
in interfaceorg.springframework.context.ApplicationListener<EventLogMessage>
-
-
-