/**
   * Tests the update of the user password by the administrator
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testChangePasswordByAdmin() throws Exception {
    // First create a new user.
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));

    // create group.
    svc.createGroup(g);
    svc.createUser(e, uuid);
    e = svc.lookupExperimenter(uuid);
    try {
      svc.changeUserPassword(uuid, rstring(PASSWORD_MODIFIED));
    } catch (Exception ex) {
      fail("Not possible to modify the experimenter's password.");
    }
  }
  /**
   * Tests the attempt to modify the password by another user (non admin) than the one currently
   * logged in.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testChangePasswordByOtherUser() throws Exception {
    IAdminPrx prx = root.getSession().getAdminService();
    // add a new user
    String groupName = iAdmin.getEventContext().groupName;
    String userName = iAdmin.getEventContext().userName;
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    // create the user.
    long userID = prx.createUser(e, groupName);
    // now the new user is going to try to modify the password
    omero.client client = new omero.client(root.getPropertyMap());
    try {
      client.createSession(uuid, groupName);
      client
          .getSession()
          .getAdminService()
          .changeUserPassword(userName, rstring(PASSWORD_MODIFIED));
      fail("The user should not have been able to modify the password.");
    } catch (Exception ex) {

    }
    client.closeSession();
  }
  /**
   * Tests the upload of the user picture.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testUploadMyUserPhoto() throws Exception {
    IAdminPrx svc = root.getSession().getAdminService();
    // First create a new user.
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));

    // create group.
    svc.createGroup(g);
    // create the user.
    svc.createUser(e, uuid);
    omero.client client = new omero.client(root.getPropertyMap());
    try {
      client.createSession(uuid, uuid);
      IAdminPrx prx = client.getSession().getAdminService();
      long id = prx.uploadMyUserPhoto("/tmp/foto.jpg", "image/jpeg", new byte[] {1});
      assertTrue(id >= 0);
    } finally {
      client.closeSession();
    }
  }
  /**
   * Tests the deletion of an experimenter.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testDeleteExperimenter() throws Exception {
    // First create a new user.
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));

    // create group.
    svc.createGroup(g);
    long id = svc.createUser(e, uuid);
    e = svc.lookupExperimenter(uuid);
    svc.deleteExperimenter(e);
    ParametersI p = new ParametersI();
    p.addId(id);
    IQueryPrx query = root.getSession().getQueryService();
    e =
        (Experimenter)
            query.findByQuery("select distinct e from Experimenter e where e.id = :id", p);
    assertNull(e);
  }
  /**
   * Tests the addition of existing user by the owner of the group. The owner is NOT an
   * administrator.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test(enabled = true)
  public void testOwnerAddExistingExperimenterToGroup() throws Exception {
    // First create a new user.
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));

    // create group.
    long groupId = svc.createGroup(g);
    g = svc.lookupGroup(uuid);
    // create the user.
    long expId = svc.createUser(e, uuid);
    Experimenter owner = svc.lookupExperimenter(uuid);
    // set the user as the group owner.
    svc.setGroupOwner(g, owner);

    // create another group and user
    String uuidGroup = UUID.randomUUID().toString();
    ExperimenterGroup g2 = new ExperimenterGroupI();
    g2.setName(omero.rtypes.rstring(uuidGroup));
    g2.getDetails().setPermissions(new PermissionsI("rw----"));
    svc.createGroup(g2);

    String uuid2 = UUID.randomUUID().toString();
    e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid2));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    expId = svc.createUser(e, uuidGroup);
    e = svc.lookupExperimenter(uuid2);
    // owner logs in.
    omero.client client = newOmeroClient();
    client.createSession(uuid, uuid);
    init(client);
    // iAdmin.
    List<ExperimenterGroup> groups = new ArrayList<ExperimenterGroup>();
    groups.add(g);
    iAdmin.addGroups(e, groups);
  }
  /**
   * Tests the update of the details of the user currently logged in using the <code>
   * updateExperimenter</code> method.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test(enabled = true)
  public void testUpdateExperimenterByUserUsingUpdateExperimenter() throws Exception {
    // First create a new user.
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));

    // create group.
    svc.createGroup(g);

    long id = svc.createUser(e, uuid);
    IQueryPrx query = root.getSession().getQueryService();
    ParametersI p = new ParametersI();
    p.addId(id);
    e =
        (Experimenter)
            query.findByQuery("select distinct e from Experimenter e where e.id = :id", p);
    assertNotNull(e);

    String name = "userModified";
    // uuid = UUID.randomUUID().toString();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring(name));
    e.setLastName(omero.rtypes.rstring(name));
    //
    // owner logs in.
    omero.client client = newOmeroClient();
    client.createSession(uuid, uuid);
    init(client);
    iAdmin.updateExperimenter(e);
    e =
        (Experimenter)
            query.findByQuery("select distinct e from Experimenter e where e.id = :id", p);
    assertNotNull(e);
    assertTrue(e.getOmeName().getValue().equals(uuid));
    assertTrue(e.getFirstName().getValue().equals(name));
    assertTrue(e.getLastName().getValue().equals(name));
  }
  /**
   * Tests the default group of an experimenter.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testChangeDefaultGroup() throws Exception {
    // Create 2 groups and add a user
    String uuid1 = UUID.randomUUID().toString();
    ExperimenterGroup g1 = new ExperimenterGroupI();
    g1.setName(omero.rtypes.rstring(uuid1));
    g1.getDetails().setPermissions(new PermissionsI("rw----"));

    String uuid2 = UUID.randomUUID().toString();
    ExperimenterGroup g2 = new ExperimenterGroupI();
    g2.setName(omero.rtypes.rstring(uuid2));
    g2.getDetails().setPermissions(new PermissionsI("rw----"));

    IAdminPrx svc = root.getSession().getAdminService();
    IQueryPrx query = root.getSession().getQueryService();
    long id1 = svc.createGroup(g1);
    long id2 = svc.createGroup(g2);

    ParametersI p = new ParametersI();
    p.addId(id1);

    ExperimenterGroup eg1 =
        (ExperimenterGroup)
            query.findByQuery("select distinct g from ExperimenterGroup g where g.id = :id", p);
    p = new ParametersI();
    p.addId(id2);

    ExperimenterGroup eg2 =
        (ExperimenterGroup)
            query.findByQuery("select distinct g from ExperimenterGroup g where g.id = :id", p);
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid1));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));

    List<ExperimenterGroup> groups = new ArrayList<ExperimenterGroup>();
    // method tested elsewhere
    ExperimenterGroup userGroup = svc.lookupGroup(USER_GROUP);
    groups.add(eg1);
    groups.add(eg2);
    groups.add(userGroup);

    long id = svc.createExperimenter(e, eg1, groups);
    e = svc.lookupExperimenter(uuid1);
    List<GroupExperimenterMap> links = e.copyGroupExperimenterMap();
    assertTrue(groups.get(0).getId().getValue() == eg1.getId().getValue());
    svc.setDefaultGroup(e, eg2);

    e = svc.lookupExperimenter(uuid1);
    links = e.copyGroupExperimenterMap();
    groups = new ArrayList<ExperimenterGroup>();
    for (GroupExperimenterMap link : links) {
      groups.add(link.getParent());
    }
    assertTrue(groups.get(0).getId().getValue() == eg2.getId().getValue());
  }
  /**
   * Tests the creation of a user using the <code>createUser</code> method.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testCreateUser() throws Exception {
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));
    long groupId = svc.createGroup(g);

    long id = svc.createUser(e, uuid);
    IQueryPrx query = root.getSession().getQueryService();

    // Check if we have a user
    ParametersI p = new ParametersI();
    p.addId(id);
    e =
        (Experimenter)
            query.findByQuery("select distinct e from Experimenter e where e.id = :id", p);
    assertNotNull(e);
    assertTrue(e.getOmeName().getValue().equals(uuid));
    // check if we are in the correct group i.e. user and uuid
    // now check if the user is in correct groups.
    ExperimenterGroup userGroup = svc.lookupGroup(USER_GROUP);
    List<Long> ids = new ArrayList<Long>();
    ids.add(groupId);
    ids.add(userGroup.getId().getValue());
    p = new ParametersI();
    p.addLongs("gids", ids);
    List list =
        (List)
            query.findAllByQuery(
                "select m "
                    + "from GroupExperimenterMap as m "
                    + "left outer join fetch m.child "
                    + "left outer join fetch m.parent"
                    + " where m.parent.id in (:gids)",
                p);
    assertNotNull(list);
    Iterator i = list.iterator();
    GroupExperimenterMap geMap;
    int count = 0;
    while (i.hasNext()) {
      geMap = (GroupExperimenterMap) i.next();
      if (geMap.getChild().getId().getValue() == id) count++;
    }
    assertTrue(count == 2);
  }
  /**
   * Tests the creation of a user using the <code>createUser</code> method. A group not created is
   * specified as the default group, in that case, an exception should be thrown.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testCreateUserNoGroup() throws Exception {
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    try {
      svc.createUser(e, uuid);
      fail("The user should not have been created. No group specified.");
    } catch (Exception ex) {
    }
  }
  @Test(enabled = false)
  public void testSudoCreatesUserAccountThroughIAdmin() throws Exception {
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(rstring(UUID.randomUUID().toString()));
    getSudoAdmin("ome").createGroup(g);
    Experimenter e = new ExperimenterI();
    e.setOmeName(rstring(UUID.randomUUID().toString()));
    e.setFirstName(rstring("ticket:181"));
    e.setLastName(rstring("ticket:199"));
    e =
        getSudoAdmin("ome")
            .getExperimenter(getSudoAdmin("ome").createUser(e, g.getName().getValue()));
    assertCanLogin(e.getOmeName().getValue(), "");
    assertCanLogin(e.getOmeName().getValue(), "ome");
    assertCanLogin(e.getOmeName().getValue(), "bob");

    doesNotHaveSystemPrivileges(e);
  }
  @Test(enabled = false)
  public void testSudoCreatesSystemAccountThroughIAdmin() throws Exception {
    Experimenter e = new ExperimenterI();
    e.setOmeName(rstring(UUID.randomUUID().toString()));
    e.setFirstName(rstring("ticket:181"));
    e.setLastName(rstring("ticket:199"));
    e = getSudoAdmin("ome").getExperimenter(getSudoAdmin("ome").createSystemUser(e));
    assertCanLogin(e.getOmeName().getValue(), "");
    assertCanLogin(e.getOmeName().getValue(), "ome");
    assertCanLogin(e.getOmeName().getValue(), "bob");

    hasSystemPrivileges(e);

    getSudoAdmin("ome").changeUserPassword(e.getOmeName().getValue(), rstring("bob"));

    assertCannotLogin(e.getOmeName().getValue(), "");
    assertCannotLogin(e.getOmeName().getValue(), "ome");
    assertCanLogin(e.getOmeName().getValue(), "bob");
  }
  /**
   * Tests to make a user the owner of a group.
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testSetOwner() throws Exception {
    // First create a new user.
    String uuid = UUID.randomUUID().toString();
    Experimenter e = new ExperimenterI();
    e.setOmeName(omero.rtypes.rstring(uuid));
    e.setFirstName(omero.rtypes.rstring("user"));
    e.setLastName(omero.rtypes.rstring("user"));
    IAdminPrx svc = root.getSession().getAdminService();

    // already tested
    ExperimenterGroup g = new ExperimenterGroupI();
    g.setName(omero.rtypes.rstring(uuid));
    g.getDetails().setPermissions(new PermissionsI("rw----"));

    // create group.
    long groupId = svc.createGroup(g);
    g = svc.lookupGroup(uuid);
    // create the user.
    long expId = svc.createUser(e, uuid);
    e = svc.lookupExperimenter(uuid);
    // set the user as the group owner.
    svc.setGroupOwner(g, e);
    IQueryPrx query = root.getSession().getQueryService();
    String sql = "select m from GroupExperimenterMap as m ";
    sql += "left outer join fetch m.child as c ";
    sql += "left outer join fetch m.parent as p ";
    sql += "where ";
    sql += "c.id = :expId ";
    sql += " and p.id = :groupId";
    ParametersI p = new ParametersI();
    p.addLong("expId", expId);
    p.addLong("groupId", groupId);
    List l = (List) query.findAllByQuery(sql, p);
    Iterator i = l.iterator();
    GroupExperimenterMap map;
    while (i.hasNext()) {
      map = (GroupExperimenterMap) i.next();
      assertTrue(map.getOwner().getValue());
    }
  }
  /**
   * Tests the adding and modifying of a user photo, specify all the exception thrown by ticket:1791
   *
   * @throws Exception Thrown if an error occurred.
   */
  @Test
  public void testUserPhoto() throws Exception {
    IAdminPrx prx = root.getSession().getAdminService();
    String uuid = UUID.randomUUID().toString();
    // First create a user in two groups, one rwrw-- and one rwr---
    ExperimenterGroup rwr = new ExperimenterGroupI();
    rwr.setName(rstring(uuid));
    rwr.getDetails().setPermissions(new PermissionsI("rwr---"));
    long rwrID = prx.createGroup(rwr);
    rwr = prx.getGroup(rwrID);

    ExperimenterGroup rwrw = new ExperimenterGroupI();
    rwrw.setName(rstring(UUID.randomUUID().toString()));
    rwr.getDetails().setPermissions(new PermissionsI("rwrw--"));
    long rwrwID = prx.createGroup(rwrw);
    rwrw = prx.getGroup(rwrwID);

    Experimenter e = new ExperimenterI();
    e.setOmeName(rstring(uuid));
    e.setFirstName(rstring(uuid));
    e.setLastName(rstring(uuid));
    long userID = prx.createUser(e, rwrw.getName().getValue());
    e = prx.getExperimenter(userID);

    prx.addGroups(e, Arrays.asList(rwr));

    omero.client client = new omero.client(root.getPropertyMap());
    try {
      client.createSession(e.getOmeName().getValue(), "foo");
      prx = client.getSession().getAdminService();
      prx.uploadMyUserPhoto("/tmp/foto.jpg", "image/jpeg", new byte[] {1});
      client.getSession().setSecurityContext(new ExperimenterGroupI(rwrID, false));
      prx.uploadMyUserPhoto("/tmp/foto2.jpg", "image/jpeg", new byte[] {2});
    } finally {
      client.closeSession();
    }
  }