public static OMEROMetadataStoreClient mockStore(ServiceFactory sf, String password)
      throws Exception {

    System.setProperty("omero.testing", "true");
    OmeroContext inner = sf.getContext();
    OmeroContext outer =
        new OmeroContext(
            new String[] {
              "classpath:ome/services/messaging.xml", // To share events
              "classpath:ome/formats/fixture.xml",
              "classpath:ome/services/blitz-servantDefinitions.xml",
              "classpath:ome/services/throttling/throttling.xml",
              "classpath:ome/config.xml"
            },
            false);
    outer.setParent(inner);
    outer.refresh();

    EventContext ec = sf.getAdminService().getEventContext();
    String username = ec.getCurrentUserName();
    long groupid = ec.getCurrentGroupId();

    MockFixture fixture = new MockFixture(new MockObjectTestCase() {}, outer);
    omero.client client = fixture.newClient();
    // Fixing group permissions from 4.2.0
    client
        .createSession(username, password)
        .setSecurityContext(new omero.model.ExperimenterGroupI(groupid, false));
    OMEROMetadataStoreClient store = new OMEROMetadataStoreClient();
    store.initialize(client);
    return store;
  }
  public boolean doLogin(boolean readOnly, boolean isClose) {

    try {
      secSys.loadEventContext(readOnly, isClose);
    } catch (SessionTimeoutException ste) {
      // If this is a CloseOnNoSessionContext then we skip all handling
      // since almost any action by the close() method will try to load
      // the context and will fail. This assumes that EventHandler is
      // the most inner handler. If this changes, then this logic may
      // need to be pushed down further.
      if (ste.sessionContext instanceof BasicSecurityWiring.CloseOnNoSessionContext) {
        log.debug("CloseOnNoSessionContext. Skipping");
        return false;
      }
      throw ste;
    }

    // now the user can be considered to be logged in.
    EventContext ec = secSys.getEventContext();
    if (!readOnly) {
      sql.prepareSession(ec.getCurrentEventId(), ec.getCurrentUserId(), ec.getCurrentGroupId());
    }
    if (log.isInfoEnabled()) {
      StringBuilder sb = new StringBuilder();
      sb.append(" Auth:\tuser="******",group=");
      sb.append(ec.getCurrentGroupId());
      sb.append(",event=");
      sb.append(ec.getCurrentEventId());
      sb.append("(");
      sb.append(ec.getCurrentEventType());
      sb.append("),sess=");
      sb.append(ec.getCurrentSessionUuid());
      Long shareId = ec.getCurrentShareId();
      if (shareId != null) {
        sb.append(",share=");
        sb.append(shareId);
      }
      log.info(sb.toString());
    }
    return true;
  }
  /**
   * @see SecuritySystem#isGraphCritical()
   * @return
   */
  public boolean isGraphCritical() {
    EventContext ec = getCurrentEventContext();
    long gid = ec.getCurrentGroupId();
    Permissions perms = ec.getCurrentGroupPermissions();

    boolean admin = ec.isCurrentUserAdmin();
    boolean pi = ec.getLeaderOfGroupsList().contains(gid);

    if (perms.isGranted(Role.WORLD, Right.READ)) {
      // Public groups (rwrwrw) are always non-critical
      return false;
    } else if (perms.isGranted(Role.GROUP, Right.READ)) {
      // Since the object will be contained in the group,
      // then it will be readable regardless.
      return false;
    } else {
      // This is a private group. Any form of admin modification is
      // critical.
      return admin || pi;
    }
  }