Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • Setting gsh.useLegacy = true in grouper.properties.
  • Using a command line argument  (gsh.sh -forceLegacyGsh)

Escape

Escape things in groovysh with single backslash.  e.g.

Code Block
attributeValueDelegate.assignValue(RuleUtils.ruleIfConditionElName(), "\${subject.sourceId != 'g:gsa'}");


API Compability

gsh is now a core part of the Grouper API and so is always compatible with the current release.

...

Delete stem and subcontents

Command

Description

addRootStem(extension, displayExtension)

Add top-level stem to the registry

addStem(parent stem name, extension, displayExtension)

Add stem to registry

delStem(stem name)

Delete stem from registry

obliterateStem(stem name, testOnlyBoolean, deleteFromPointInTimeBoolean)    (Grouper v2.0.2+)

Delete stem, and subobjects.

If testonly (true|false), then only
print a report.  This is not supported when deleteFromPointInTime is true.

If deleteFromPointInTime (true|false), then delete from point in time as well.  Otherwise, point in time records are not deleted.

Note that point in time data can only be deleted after the actual objects have been deleted and those deletions have been processed by the changeLogTempToChangeLog job, which runs once a minute by default with the Grouper Daemon.  So when you call obliterateStem(name, false, true), it will first obliterate the actual stem, then sleep and keep checking if the changeLogTempToChangeLog job has completed.  When it completes, it will obliterate from the point in time data.

GrouperSession must be open before calling...

getStemAttr(stem name, attr)

Get value of stem attribute

getStems(name)

Find all stems with a matching naming attribute value, returns a Set of stems

setStemAttr(stem name, attr, value)

Set value of stem attribute

StemFinder.findByName(grouperSession, name)

Find one stem by name

StemFinder.findByUuid(grouperSession, uuid)

Find one stem by uuid

Delete stem and subcontents


Code Block
grouperSession = GrouperSession.startRootSession();
stem = StemFinder.findByName(grouperSession, "a");
for(child : stem.getChildGroups(Stem.Scope.SUB)) { System.out.println("deleting: " + child.getName()); child.delete();  }
stemList = new ArrayList(stem.getChildStems(Stem.Scope.SUB));
Collections.sort(stemList);
Collections.reverse(stemList);
for(childStem : stemList) { System.out.println("deleting: " + childStem.getName()); childStem.delete(); }
stem.delete();


Subjects

Command

Description

addSubject(id, type, name)

Add local subject to registry. You need the jdbc source for this to work. The type parameter describes the type of subject (e.g. "people"), and is required non-null even though there are few useful api methods to query it.

In 2.4.0.api.41+ patch, this will also create the id, name, description, and loginid attribute (unless grouper.properties create.attributes.when.creating.registry.subjects is false)

RegistrySubject.addOrUpdate(grouperSession, id, type, name, nameAttributeValue, loginid, description, email)In 2.4.0.api.41+ patch, add a registry subject like addSubject, but specify the attribute values of name, loginid, etc
e.g. RegistrySubject.addOrUpdate(grouperSession, "someTestSubject", "person", "Some Testsubject", "Name Some Test Subject", "stsub", "Some Testsubject - employee - also alumni", "some@test.subject");
RegistrySubject.find(id, errorOnNotFound)In 2.4.0.api.41+ patch, get a registry subject
e.g. registrySubject = RegistrySubject.find("someTestSubject", false);
registrySubject.delete(grouperSession)In 2.4.0.api.41+ patch, delete a registry subject
e.g. registrySubject.delete(grouperSession);
RegistrySubjectAttribute.addOrUpdate(subjectId, attributeName, attributeValue)In 2.4.0.api.41+ patch, add or update a registry subject attribute
registrySubjectAttribute.delete()In 2.4.0.api.41+ patch, delete an attribute value

findSubject(idOrIdentifier)

Find a subject by id or identifier

findSubject(idOrIdentifier, type)

Find a subject by id or identifier; type is a deprecated parameter that is ignored

findSubject(idOrIdentifier, type, source)

Find a subject by id or identifier for a specific subject source; type is a deprecated parameter that is ignored

getSources()

Find all Subject sources

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findAll(searchString, source);

Find all subjects in a source by search string

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdAndSource(id, source, exceptionIfNull);
SubjectFinder.findByIdAndSource("12345", "jdbc", true);

Find a subject by id in a certain source

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdentifierAndSource(identifier, source, exceptionIfNull);
SubjectFinder.findByIdentifierAndSource("jsmith", "jdbc", true);

Find a subject by identifier in a certain source

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdOrIdentifierAndSource(idOrIdentifier, source, exceptionIfNull);
SubjectFinder.findByIdOrIdentifierAndSource("jsmith", "jdbc", true);

Find a subject by id or identifier in a certain source

add test subjects to registry (e.g. test.subject.0 through 9)

grouperSession = GrouperSession.startRootSession();
new RegistryReset()._addSubjects();

Edit subject (in this case name)

RegistrySubject registrySubject = GrouperDAOFactory.getFactory().getRegistrySubject().find("user1a", "person", true);
registrySubject.setName("New name");
HibernateSession.byObjectStatic().update(registrySubject);

add a subject application principal with attributes (GSH)


Code Block
String principal = "someApp";
String email = null;

GrouperSession grouperSession = GrouperSession.startRootSession();


addSubject(principal, "application", principal);
HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "description", principal, principal.toLowerCase()}));
if (email != null){ HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "email", email, email.toLowerCase()}));}
HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "loginid", principal, principal}));
HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "name", principal, principal}));



remove a subject with attributes (GSH)


Code Block
String principal = "someApp";
String email = null;

GrouperSession grouperSession = GrouperSession.startRootSession();

HibernateSession.bySqlStatic().executeSql("delete from subjectattribute where subjectId = ?", GrouperUtil.toListObject(new Object[]{principal}));
HibernateSession.bySqlStatic().executeSql("delete from subject where subjectId = ?", GrouperUtil.toListObject(new Object[]{principal}));(new Object[]{principal}));


subject api diagnostics

grouper.properties (temporarily)

Code Block
gsh.exitOnSubjectCheckConfigProblem = false

gsh

Code Block
GrouperSession.startRootSession();
new edu.internet2.middleware.grouper.grouperUi.serviceLogic.SubjectSourceDiagnostics().assignSourceId("SMUPerson_DEV").assignSubjectId("empl1").assignSubjectIdentifier("netid@school.edu").assignSearchString("em").subjectSourceDiagnosticsFromGsh()
===>
SUCCESS: Found subject by id in 37ms: 'empl1'
         with SubjectFinder.findByIdAndSource("empl1", "SMUPerson_DEV", false)
SUCCESS: Subject id in returned subject matches the subject id searched for: 'empl1'
WARNING: No subject found by identifier in 14ms: 'netid@school.edu'
         with SubjectFinder.findByIdentifierAndSource("netid@school.edu", "SMUPerson_DEV", false)


System

Command

Description

sqlRun(file)

Execute each line of a sql file, just like ant would.  This can run the files generated by registryInitializeSchema()

sqlRun(string)

Executes a single sql statement

:exit

Terminate shell

help()

Display usage information

p(command)

Pretty print results.

:quit

Terminate shell

version()

Return version information

...

Command

Description

help("transaction")

print help information

transactionStatus()

print the list of nested transactions

transactionStart("<GrouperTransactionType>")

start a transaction, or make sure one is already started
   Can use: "READONLY_OR_USE_EXISTING", "NONE", "READONLY_NEW",
"READ_WRITE_OR_USE_EXISTING", "READ_WRITE_NEW"

transactionCommit("<GrouperCommitType>")

commit a transaction
   Can use: "COMMIT_NOW", "COMMIT_IF_NEW_TRANSACTION

transactionRollback("<GrouperRollbackType>")

rollback a transaction
    Can use: "ROLLBACK_NOW", "ROLLBACK_IF_NEW_TRANSACTION

transactionEnd()

end a transaction
    Note if it was read/write, and not committed or rolled back, this will commit and end

Daemon

You can schedule daemon jobs (and in UI) in v2.5.23+

Code Block
GrouperSession.startRootSession();
edu.internet2.middleware.grouper.app.loader.GrouperLoader.scheduleJobs();


Loader

Above, it describes how you can kick off the loader in daemon mode.  You can also execute one job with:

...

Code Block
# (1) Print tab-separated summary of all group members, and flags for direct, indirect, or both
# Depending on the results, you could use the data to create a scrutinized list of Ids to delete, then import it and delete in a loop

me = SubjectFinder.findByIdentifierAndSource("my-username", "pid", true);
session = GrouperSession.start(me);
// OR: session = GrouperSession.startRootSession(True)

group = GroupFinder.findByName(session, "tmp:my:group", true);

effectiveMembers = group.getEffectiveMembers();
immediateMembers = group.getImmediateMembers();

System.out.println(String.join("\t", "id", "name", "Effective", "Immediate"));

for (Member m: group.getMembers()) {
    System.out.print(m.getSubject().getId() + "\t" + m.getSubject().getName() + "\t");
    System.out.print(effectiveMembers.contains(m).toString() + "\t");
    System.out.println(immediateMembers.contains(m).toString() + "\t");
}



# (2) Get the immediate and effective members for a specific source ("pid" in this example), intersect them to find the redundant ones
# This has a dryRun flag, so you can test first

sources = new HashSet<Source>()
sources.add(SourceManager.getInstance().getSource("pid"))

effectiveUsers = group.getEffectiveMembers(Group.getDefaultList(), sources, null)
immediateUsers = group.getImmediateMembers(Group.getDefaultList(), sources, null)

# use retainAll() to find the intersection; i.e., users both as effective and immediate member
immediateUsers.retainAll(effectiveUsers)

System.out.println("There are " + immediateUsers.size() + " users having both direct + indirect memberships");

dryRun = true

for (Member m: immediateUsers) {
    if (dryRun) {
        System.out.println("Ok to delete " + m.getSubject().getId());
    } else {
        System.out.println("Deleting " + m.getSubject().getId());
        group.deleteMember(m, false);
    }
}

# (3) Get the groups this subject is a member of. Note that a group is a kind of subject, and has a toSubject() method to convert it.

import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer

GrouperSession grouperSession = GrouperSession.startRootSession();

Group group = GroupFinder.findByName(grouperSession, "test:testGroup", true);
Subject subject = g.toSubject();

Set<MembershipSubjectContainer> msc = new MembershipFinder().addSubject(subject).findMembershipResult().getMembershipSubjectContainers();

for (MembershipSubjectContainer membershipSubjectContainer : msc) { println(membershipSubjectContainer.getGroupOwner().getName());}

//Note there are a few other options for the search. Add these to the MembershipFinder method chain before calling findMembershipResult():
//  - search immediate, effective, etc. (needs to import MembershipType)
import edu.internet2.middleware.grouper.membership.MembershipType
membershipFinder.assignMembershipType(MembershipType.IMMEDIATE) // options are IMMEDIATE|NONIMMEDIATE|EFFECTIVE|COMPOSITE
//  - retrieve specific groups based on pattern
membershipFinder.assignScope("%:test:%")
//  - Enabled status -- true means enabled only, false, means disabled only, and null means all
membershipFinder.assignEnabled(false)
// For other methods, refer to the Javadoc at httphttps://software.internet2.github.ioedu/grouper/doc/master/grouper-parent/apidocs/index.html?edu/internet2/middleware/grouper/MembershipFinder.html

...

Code Block
gcDbAccess = new edu.internet2.middleware.grouperClient.jdbc.GcDbAccess();
gcDbAccess.connectionName("warehouse").sql("select count(1) from grouper_groups").select(int.class);


Set password using Grouper built-in authentication

Code Block
v2.5.29+
new GrouperPasswordSave().assignApplication(GrouperPassword.Application.UI).assignUsername("username").assignPassword("password").save();