/**
  * It suffices to set the {@link Details} to a new instance to make this context unusable. {@link
  * #isReady()} will return false.
  */
 public void invalidateCurrentEventContext() {
   BasicEventContext c = current();
   c.invalidate();
   if (log.isDebugEnabled()) {
     log.debug("Invalidated login: " + c);
   }
 }
 /**
  * Checks if the current {@link Thread} has non-null {@link Experimenter}, {@link Event}, and
  * {@linkExperimenterGroup}, required for proper functioning of the security system.
  */
 public boolean isReady() {
   BasicEventContext c = current();
   if (c.getEvent() != null && c.getGroup() != null && c.getOwner() != null) {
     return true;
   }
   return false;
 }
 public int logout() {
   LinkedList<BasicEventContext> list = list();
   BasicEventContext bec = list.removeLast();
   bec.getStats().methodOut();
   if (log.isDebugEnabled()) {
     log.debug("Logged out: " + bec);
   }
   return list.size();
 }
  public Event newEvent(Session session, EventType type, TokenHolder tokenHolder) {
    BasicEventContext c = current();
    Event e = new Event();
    e.setType(type);
    e.setTime(new Timestamp(System.currentTimeMillis()));
    tokenHolder.setToken(e.getGraphHolder());
    e.getDetails().setPermissions(Permissions.READ_ONLY);
    // Proxied if necessary
    e.setExperimenter(c.getOwner());
    e.setExperimenterGroup(c.getGroup());
    e.setSession(session);

    c.setEvent(e);
    return e;
  }
 /**
  * Login method which can be used by the security system to replace the existing {@link
  * BasicEventContext}.
  */
 public void login(BasicEventContext bec) {
   if (log.isDebugEnabled()) {
     log.debug("Logging in :" + bec);
   }
   list().add(bec);
   bec.getStats().methodIn();
 }
  public void addLog(String action, Class klass, Long id) {

    Assert.notNull(action);
    Assert.notNull(klass);
    Assert.notNull(id);

    if (Event.class.isAssignableFrom(klass) || EventLog.class.isAssignableFrom(klass)) {
      if (log.isDebugEnabled()) {
        log.debug("Not logging creation of logging type:" + klass);
      }
      return; // EARLY EXIT
    } else {
      if (!isReady()) {
        throw new InternalException("Not ready to add EventLog");
      }
    }

    if (log.isInfoEnabled()) {
      log.info("Adding log:" + action + "," + klass + "," + id);
    }

    BasicEventContext c = current();
    List<EventLog> list = current().getLogs();
    if (list == null) {
      list = new ArrayList<EventLog>();
      c.setLogs(list);
    }

    EventLog l = new EventLog();
    l.setAction(action);
    l.setEntityType(klass.getName()); // TODO could be id to Type entity
    l.setEntityId(id);
    l.setEvent(c.getEvent());
    Details d = Details.create();
    d.setPermissions(new Permissions());
    l.getDetails().copy(d);
    list.add(l);
  }
  /**
   * delegates to SecurityFilter because that is where the logic is defined for the {@link
   * #enableReadFilter(Object) read filter}
   *
   * <p>Ignores the id for the moment.
   *
   * <p>Though we pass in whether or not a share is active for completeness, a different {@link
   * ACLVoter} implementation will almost certainly be active for share use.
   */
  public boolean allowLoad(Class<? extends IObject> klass, Details d, long id) {
    Assert.notNull(klass);

    if (d == null
        || sysTypes.isSystemType(klass)
        || sysTypes.isInSystemGroup(d)
        || sysTypes.isInUserGroup(d)) {
      return true;
    }

    final BasicEventContext c = currentUser.current();
    final boolean nonPrivate =
        c.getCurrentGroupPermissions().isGranted(Role.GROUP, Right.READ)
            || c.getCurrentGroupPermissions().isGranted(Role.WORLD, Right.READ);
    final boolean isShare = c.getCurrentShareId() != null;
    final boolean adminOrPi =
        c.isCurrentUserAdmin() || c.getLeaderOfGroupsList().contains(c.getCurrentGroupId());
    return securityFilter.passesFilter(
        d, c.getGroup().getId(), c.getOwner().getId(), nonPrivate, adminOrPi, isShare);
  }
 /**
  * Creates a {@link Details} object for the current security context.
  *
  * <p>The {@link Permissions} on the instance are calculated from the current group as well as the
  * user's umask.
  *
  * @return
  * @see <a href="https://trac.openmicroscopy.org.uk/trac/omero/ticket:1434">ticket:1434</a>
  */
 public Details createDetails() {
   BasicEventContext c = current();
   Details d = Details.create();
   d.setCreationEvent(c.getEvent());
   d.setUpdateEvent(c.getEvent());
   d.setOwner(c.getOwner());
   d.setGroup(c.getGroup());
   // ticket:1434
   Permissions groupPerms = c.getCurrentGroupPermissions();
   Permissions userUmask = c.getCurrentUmask();
   Permissions p = new Permissions(groupPerms);
   p.revokeAll(userUmask);
   d.setPermissions(p);
   return d;
 }
 /**
  * Take all values during loadEventContext() in one shot. Event is set during {@link
  * #newEvent(long, EventType, TokenHolder)} and possibly updated via {@link #updateEvent(Event)}.
  */
 void setValues(
     Experimenter owner,
     ExperimenterGroup group,
     boolean isAdmin,
     boolean isReadOnly,
     Long shareId) {
   BasicEventContext c = current();
   c.setOwner(owner);
   c.setGroup(group);
   c.setAdmin(isAdmin);
   c.setReadOnly(isReadOnly);
   c.setShareId(shareId);
 }
  private boolean allowUpdateOrDelete(IObject iObject, Details trustedDetails, boolean update) {
    Assert.notNull(iObject);

    BasicEventContext c = currentUser.current();
    Long uid = c.getCurrentUserId();

    boolean sysType =
        sysTypes.isSystemType(iObject.getClass()) || sysTypes.isInSystemGroup(iObject.getDetails());

    // needs no details info
    if (tokenHolder.hasPrivilegedToken(iObject)) {
      return true; // ticket:1794, allow move to "user
    } else if (update && !sysType && currentUser.isGraphCritical()) { // ticket:1769
      return objectBelongsToUser(iObject, uid);
    } else if (c.isCurrentUserAdmin()) {
      return true;
    } else if (sysType) {
      return false;
    }

    // previously we were taking the details directly from iObject
    // iObject, however, is in a critical state. Values such as
    // Permissions, owner, and group may have been changed.
    Details d = trustedDetails;

    // this can now only happen if a table doesn't have permissions
    // and there aren't any of those. so let it be updated.
    if (d == null) {
      return true;
    }

    // the owner and group information might be null if the type
    // is intended to be a system-type but isn't marked as one
    // via SecuritySystem.isSystemType(). A NPE here might imply
    // that that information is out of sync.
    Long o = d.getOwner() == null ? null : d.getOwner().getId();
    Long g = d.getGroup() == null ? null : d.getGroup().getId();

    // needs no permissions info
    if (g != null && c.getLeaderOfGroupsList().contains(g)) {
      return true;
    }

    Permissions p = d.getPermissions();

    // this should never occur.
    if (p == null) {
      throw new InternalException(
          "Permissions null! Security system "
              + "failure -- refusing to continue. The Permissions should "
              + "be set to a default value.");
    }

    // standard
    if (p.isGranted(WORLD, WRITE)) {
      return true;
    }
    if (p.isGranted(USER, WRITE) && o != null && o.equals(c.getOwner().getId())) {
      return true;
    }
    /* ticket:1992 - removing concept of GROUP-WRITE
    if (p.isGranted(GROUP, WRITE) && g != null
            && c.getMemberOfGroupsList().contains(g)) {
        return true;
    }
    */

    return false;
  }