Appending perforce permission table through java results in blank permission table - java

I am trying to grant permission to a group on a folder in Perforce. However, the permission table that is created/updated from Java in Perforce is empty.
Following are the steps that I do -
//Get the server object.
IOptionsServer server = ServerFactory.getOptionsServer("p4java://<ip>:1666", null);
server.connect();
server.setUserName("<username>"); // this is a super user
server.login("<password>");
//Create a user group and add users.
IUserGroup ug = new UserGroup();
String groupName = "<usergroup_somename>;
ug.setName(groupName);
List<String> userList = new ArrayList<>();
userList.add("<username1>");
userList.add("<username2>");
userList.add("<username3>");
ug.setUsers(userList);
server.createUserGroup(ug);
//Get the permission table.
GetProtectionEntriesOptions gpo = new GetProtectionEntriesOptions();
gpo.setAllUsers(true);
List<IProtectionEntry> peList = server.getProtectionEntries(null, gpo);
//Create a new Protection entry
IProtectionEntry pe = new ProtectionEntry();
pe.setGroup(true);
pe.setName(groupName);
depotFilePath = "//depottest/Level1/Level2/..."; // the folders exist in Perforce
pe.setPath(depotFilePath);
pe.setMode("write");
pe.setHost("*");
pe.setPathExcluded(false);
pe.setOrder(peList.size());
pe.setType(EntryType.INCLUDE);
//Add the new created permission into the fetched Permission table list.
peList.add(pe);
//Create/Update the Permission table using either of the following methods separately or in combination creates a blank permission table.
server.createProtectionEntries(peList);
server.updateProtectionEntries(peList);
According to the documentation the methods in the end should create/replace/update the Permission table, however, this does not happen and instead the permission table in the Perforce server is deleted/blank.
I may be missing something. Can someone please give some suggestions on how to fix this?
P.S. I have tried using only the updateProtectionEntries(peList) method or the server.createProtectionEntries(peList) method and both together and still the pemission table in the Perforce server is blank.

Perforce has forums where you can ask questions: forums.perforce.com
At one time (depends on P4Java and server versions) incorrect order values could lose data. There's also a spaces-in-path problem.
This works for me:
peList.add(pe);
// fix order values and spaces-in-path quoting
int i = 0;
for (IProtectionEntry pe : peList) {
pe.setOrder(i++);
if (pe.getPath().indexOf(" ") >= 0) {
// this bug should be fixed in 2014.X (no promises)
if (pe.isPathExcluded()) {
pe.setPath("\"-" + pe.getPath() + "\"");
pe.setPathExcluded(false);
} else {
pe.setPath("\"" + pe.getPath() + "\"");
}
}
}
try {
String createProtectionEntries = server.createProtectionEntries(peList);

Related

Adding User on LDAP via JNDI (Java) -> NoPermissionError

First i want to explain what i want to do and how the code is looking:
I want to add a User via JNDI on my LDAP with JAVA, i added following code:
public void addUser(String firstName, String lastName, String number) throws NamingException {
Properties initialProperties = new Properties();
initialProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
initialProperties.put(Context.PROVIDER_URL, "***");
initialProperties.put(Context.SECURITY_AUTHENTICATION, "simple");
initialProperties.put(Context.SECURITY_PRINCIPAL, "***");
initialProperties.put(Context.SECURITY_CREDENTIALS, "***");
DirContext context = new InitialDirContext(initialProperties);
BasicAttributes attributes = new BasicAttributes();
Attribute attribute = new BasicAttribute("objectClass");
attribute.add("top");
attribute.add("person");
attribute.add("organizationalPerson");
attribute.add("inetOrgPerson");
Attribute sn = new BasicAttribute("sn");
Attribute cn = new BasicAttribute("cn");
sn.add(lastName);
cn.add(firstName);
attributes.put(sn);
attributes.put(cn);
attributes.put(attribute);
try {
context.createSubcontext("***", attributes);
} catch(NamingException e) {
e.printStackTrace();
}
}
When i call the method i get following error:
javax.naming.NoPermissionException: [LDAP: error code 50 - 00000005: SecErr: DSID-031528D2, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
Which makes no sense in my point of view because i created two other methods, one for getting all the users which works and one for editing a user which works too, so i have the rights to read and write a user, but when i want to create a user it says i have no permission ?
Do anyone else had this problem?
Is there any configuration on the Administrator user necessary on the LDAP? But the Administrator should be have all rights?
I hope anyone can help me! :)
Greetings,
Fabian.
so i have the rights to read and write a user, but when i want to create a user it says i have no permission
Read, write and create are 3 separate permissions. A user can have write permissions to existing objects, but not have permission to create a new object. Those permissions can be set differently on each OU.

How to copy an existing organisation role in Liferay and add it to Users that already had the original role?

So i am working with Liferay 7/Oracle 11g and i try to copy existing organization roles of a specified subtype, rename them and then add those new roles to users that had the original Roles.
So getting roles by subtype works pretty straightforward,
the first Problem arises after i add the new role, i receive an error message when trying to view the new Role:
Someone may be trying to circumvent the permission checker: {companyId=20115, name=com.liferay.portal.kernel.model.Role, primKey=31701, scope=4}
the second Problem is getting the Users that have the original Organization Role as i can't find an existing Liferay class that delivers me that Information. From what i know its saved withing the USERGROUPROLE table, so i could read it from there with my own SQL select, but i would prefer if there was a Liferay class that provided that information.
List<Role> lRole = RoleLocalServiceUtil.getSubtypeRoles(String.valueOf(adoptFromYear));
for(Role role : lRole) {
long roleId = CounterLocalServiceUtil.increment();
Role newRole = RoleLocalServiceUtil.createRole(roleId);
newRole.setClassPK(roleId);
newRole.setCompanyId(role.getCompanyId());
newRole.setUserId(role.getUserId());
newRole.setUserName(role.getUserName());
newRole.setClassName(role.getClassName());
newRole.setTitle(role.getTitle());
newRole.setDescription(role.getDescription());
newRole.setCreateDate(new Date());
newRole.setType(role.getType());
newRole.setName(replaceOrAppendYear(role.getName(), newYear));
newRole.setSubtype(String.valueOf(newYear));
RoleLocalServiceUtil.addRole(newRole);
//assign Users that have base Role, the new Role
long[] aUserId = UserLocalServiceUtil.getRoleUserIds(role.getRoleId());
for(long userId : aUserId) {
RoleLocalServiceUtil.addUserRole(userId, newRole.getRoleId());
}
}
UPDATE:
I fixed the first problem by using another addRole method of UserLocalServiceUtil, code is now as following:
List<Role> lRole = RoleLocalServiceUtil.getSubtypeRoles(String.valueOf(adoptFromYear));
for(Role role : lRole) {
Role newRole = RoleLocalServiceUtil.addRole(role.getUserId(), Role.class.getName(),
CounterLocalServiceUtil.increment(), replaceOrAppendYear(role.getName(), newYear),
role.getTitleMap(), role.getDescriptionMap(), role.getType(),
String.valueOf(newYear), null);
//add User from base Role to new Role
long[] aUserId = UserLocalServiceUtil.getRoleUserIds(role.getRoleId());
//aUserId still empty
for(long userId : aUserId) {
RoleLocalServiceUtil.addUserRole(userId, newRole.getRoleId());
}
}
So the Problem of getting all User that have a certain Organization Role still exists.
So my solution to my problems is as following, i used the other addRole method to add a new Role and that also creates the additional entry in the db so there is no error message anymore.
On my second problem, i just use the liferay API to get all entries from UserGroupRole Table and then i filter all the entries via the roleId that i need. Not a nice solution, but in my case even with tens of thousands of entries (and thats generous for what i work on) the function will be called once a year so ¯\_(ツ)_/¯
So here is the solution:
List<Role> lRole = RoleLocalServiceUtil.getSubtypeRoles(String.valueOf(adoptFromYear));
for(Role role : lRole) {
Role newRole = RoleLocalServiceUtil.addRole(role.getUserId(), Role.class.getName(),
CounterLocalServiceUtil.increment(), replaceOrAppendYear(role.getName(), newYear),
role.getTitleMap(), role.getDescriptionMap(), role.getType(), String.valueOf(newYear), null);
//get all User - Group (Organization) - Role Objects and filter by Role
List<UserGroupRole> lUserGroupRole = UserGroupRoleLocalServiceUtil
.getUserGroupRoles(QueryUtil.ALL_POS, QueryUtil.ALL_POS).stream()
.filter(ugr -> ugr.getRoleId() == role.getRoleId()).collect(Collectors.toList());
//add new Role to all existing Users that had the adopted role
long[] roleIds = {newRole.getRoleId()};
for(UserGroupRole ugr : lUserGroupRole) {
UserGroupRoleLocalServiceUtil.addUserGroupRoles(ugr.getUserId(), ugr.getGroupId(), roleIds);
}
}

Inserting data with UCanAccess from big text files is very slow

I'm trying to read text files .txt with more than 10.000 lines per file, splitting them and inserting the data in Access database using Java and UCanAccess. The problem is that it becomes slower and slower every time (as the database gets bigger).
Now after reading 7 text files and inserting them into database, it would take the project more than 20 minutes to read another file.
I tried to do just the reading and it works fine, so the problem is the actual inserting into database.
N.B: This is my first time using UCanAccess with Java because I found that the JDBC-ODBC Bridge is no longer available. Any suggestions for an alternative solution would also be appreciated.
If your current task is simply to import a large amount of data from text files straight into the database, and it does not require any sophisticated SQL manipulations, then you might consider using the Jackcess API directly. For example, to import a CSV file you could do something like this:
String csvFileSpec = "C:/Users/Gord/Desktop/BookData.csv";
String dbFileSpec = "C:/Users/Public/JackcessTest.accdb";
String tableName = "Book";
try (Database db = new DatabaseBuilder()
.setFile(new File(dbFileSpec))
.setAutoSync(false)
.open()) {
new ImportUtil.Builder(db, tableName)
.setDelimiter(",")
.setUseExistingTable(true)
.setHeader(false)
.importFile(new File(csvFileSpec));
// this is a try-with-resources block,
// so db.close() happens automatically
}
Or, if you need to manually parse each line of input, insert a row, and retrieve the AutoNumber value for the new row, then the code would be more like this:
String dbFileSpec = "C:/Users/Public/JackcessTest.accdb";
String tableName = "Book";
try (Database db = new DatabaseBuilder()
.setFile(new File(dbFileSpec))
.setAutoSync(false)
.open()) {
// sample data (e.g., from parsing of an input line)
String title = "So, Anyway";
String author = "Cleese, John";
Table tbl = db.getTable(tableName);
Object[] rowData = tbl.addRow(Column.AUTO_NUMBER, title, author);
int newId = (int)rowData[0]; // retrieve generated AutoNumber
System.out.printf("row inserted with ID = %d%n", newId);
// this is a try-with-resources block,
// so db.close() happens automatically
}
To update an existing row based on its primary key, the code would be
Table tbl = db.getTable(tableName);
Row row = CursorBuilder.findRowByPrimaryKey(tbl, 3); // i.e., ID = 3
if (row != null) {
// Note: column names are case-sensitive
row.put("Title", "The New Title For This Book");
tbl.updateRow(row);
}
Note that for maximum speed I used .setAutoSync(false) when opening the Database, but bear in mind that disabling AutoSync does increase the chance of leaving the Access database file in a damaged (and possibly unusable) state if the application terminates abnormally while performing the updates.
Also, if you need to use slq/ucanaccess, you have to call setAutocommit(false) on the connection at the begin, and do a commit each 200/300 record. The performances will improve drammatically (about 99%).

Retrieving modified/ checked in files from Clear Case Activity

This query is related to Rational Clear Case Cm api programming using java. We have a requirement wherein we want to get the list of modified files of a particular stream. I am able to get the list of activities which are of type CcActivity from given Stream and Using that activitylist info I am able to fetch the Version information also.
I am unable to get the changeset information ie name of files which are modified, as there is no such method defined.
Could you please help me out as to which property or method I should use to fetch the list of mopdified file or changeset information using activity id or version information. Below is the code which I have written for getting activity list information and version information:-
PropertyRequest propertyrequest = new PropertyRequest(
CcStream.ACTIVITY_LIST,CcStream.TASK_LIST
);
stream=(CcStream) stream.doReadProperties(propertyrequest);
List<CcActivity> listOfAct = stream.getActivityList();
for(int i=0;i<listOfAct.size();i++){
CcActivity ccActivity = listOfAct.get(i);
PropertyRequest activityPropertyRequest = new PropertyRequest(
CcActivity.COMMENT,CcActivity.ID,CcActivity.DISPLAY_NAME,CcActivity.LATEST_VERSION_LIST,CcActivity.CREATOR_DISPLAY_NAME,CcActivity.NAME_RESOLVER_VIEW
,CcActivity.TASK_LIST,CcActivity.CREATOR_LOGIN_NAME,CcActivity.HEADLINE,CcActivity.COMMENT);
ccActivity = (CcActivity)ccActivity.doReadProperties(activityPropertyRequest);
trace(ccActivity.getDisplayName());
trace(ccActivity.getCreatorDisplayName());
trace("CREATOR_LOGIN_NAME :" +ccActivity.getCreatorLoginName());
trace("Headline:" +ccActivity.getHeadline());
ResourceList<javax.wvcm.Version> versionList = ccActivity.getLatestVersionList();
for(int j=0;j<versionList.size();j++){
Version version = versionList.get(j);
PropertyRequest versionPropertyRequest = new PropertyRequest(
Version.PREDECESSOR_LIST,Version.VERSION_NAME,Version.VERSION_HISTORY.nest(VersionHistory.CHILD_MAP),Version.DISPLAY_NAME,Version.COMMENT
,Version.PATHNAME_LOCATION,Version.ACTIVITY.nest(Resource.CONTENT_TYPE));
version = (Version)version.doReadProperties(versionPropertyRequest);
trace("Version Info");
trace("Version Name : " + version.getVersionName());
trace("Version Comment :" +version.getComment());
Old thread but I have recently been trying to learn how to list modified files through the API. I believe the issue is that version object returned by the ResourceList get method should be cast to CcVersion type.
This exposes the StpResource.doReadProperties(Resource context, Feedback feedback) method which requires a handle to the view we are interested in. We can also request the CcVersion specific properties that we are interested in.
The example would then become something like:
ResourceList<javax.wvcm.Version> versionList = ccActivity.getLatestVersionList();
for(int j=0;j<versionList.size();j++){
Version version = versionList.get(j);
PropertyRequest versionPropertyRequest = new PropertyRequest(CcVersion.DISPLAY_NAME, CcVersion.VIEW_RELATIVE_PATH, CcVersion.CREATION_DATE);
version = (CcVersion) version.doReadProperties(view, versionPropertyRequest);
trace("Version Info");
trace("Version DISPLAY_NAME : " + version.getDisplayName());
trace("Version VIEW_RELATIVE_PATH : " + version.getViewRelativePath());
trace("Version CREATION_DATE : " + version.getCreationDate());
}

Get list of Active Directory users with authenticated identity thru Waffle (Java)?

I want to allow a user to authenticate and retrieve a full list of Active Directory users without having to enter their password. I'm able to authenticate easily through Waffle and can query information specific to the authenticated user, like the list of groups to which they belong. However, Waffle doesn't seem to have the ability to make more general queries like the full list of users (or even the list of users belonging to a certain group).
I have another toy example configured where I use the JNDI to query the user list, which works fine, but it requires a username and password in order to make the connection.
Assuming anonymous querying is disabled on my AD server, is there any way for me to use the authenticated session I've established through Waffle to query the list of users?
Figured it out, in case anyone is interested. Honestly surprised I didn't get an answer or find a clear-cut solution somewhere online. It turns out that Waffle is unnecessary for a simple user list query - I modified the code sample here to produce the following method which does the trick:
static void queryCom4j(){
IADs rootDSE = COM4J.getObject(IADs.class, "LDAP://RootDSE", null);
String namingContext = (String)rootDSE.get("defaultNamingContext");
_Connection conn = ClassFactory.createConnection();
conn.provider("ADsDSOObject");
conn.open("Active Directory Provider","","",-1);
_Command cmd = ClassFactory.createCommand();
cmd.activeConnection(conn);
String fields = "distinguishedName,userPrincipalName,telephoneNumber,mail";
String query = "(&(objectclass=user)(objectcategory=person))";
cmd.commandText("<LDAP://" + namingContext + ">;" + query + ";" + fields + ";subTree");
_Recordset rs = cmd.execute(null, Variant.getMissing(), -1);
System.out.println("Found " + rs.recordCount() + " users");
while (!rs.eof()){
for (int i = 0; i < fields.split(",").length; i++){
Object value = rs.fields().item(i).value();
System.out.println((value == null) ? "N/A" : value.toString());
}
rs.moveNext();
}

Categories

Resources