Call java-Agent of another DataBase from current DataBase Java-Agent - java

I have a java-agent from which I can call another agent with the parameter passed through it which contains NoteId, and using that NoteId, I am successfully able to get the work done the that document.Till here every thing is clear.
The main question regarding this is , Is it possible to run the agent of another database on same server from the current database agent?
To be more clear for an example
I have two databases, "ABC.nsf" and "XYZ.nsf", JavaAgent "A" is in "ABC.nsf" and JavaAgent "B" is in "XYZ.nsf". In my xpage I have a button running Agent "A", and even Agent "A" can run any other javaAgent from the same database.
Code:
Document mainDoc = db.getDocumentByUNID(tempDoc.getItemValueString("mainDocId"));
String noteID = mainDoc.getNoteID();
String agentName = "NotificationManager";
Agent agent = db.getAgent(agentName);
if (agent != null)
agent.runOnServer(noteID);
else
System.err.println("Something is wrong");
But Actually I want run the JavaAgent "B" Located in "XYZ.nsf" from JavaAgent "A" which is in "ABC.nsf".
After some research I have referd this code.
Code
Database db=session.getDatabase(current_server, "path/to/XYZ.nsf");
Agent myAgent=db.getAgent("B");
myAgent.run();
And yes I am unsuccessfull there,
Need some idea to acheive this.Any suggession will be really appretiated.

The example code is correct in principle. Just some things you have to know:
First of all the name of server can either be "" or the real name of the server. BUT if there is a server, then you have to check the Trusted servers:- section in the server document (Security Tab - Server Access section). There the server himself has to be member of the field (as name or in a group), otherwise you might not be able to open the other database.
Second thing: the path to the target database is relative to data directory and has to be in the right format for the given operating system.
e.g. C:\IBM\Domino\Data\first\xyz.nsf would be first\xyz.nsf and /local/notesdata/second/abc.nsfwould be second/abc.nsf
Third: the noteid that you get is from a document from the calling database. In the "target"- agent you have to go and get the document from the source database, otherwise it will either throw an error or -as the noteid is just a sequential number- return a document from target database that has nothing to do with the document you are searching for.
The calling agent A would have code like this:
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
Database dbCurrent = agentContext.getCurrentDatabase();
Database dbTarget = session.getDatabase(dbCurrent.Server, "XYZ.nsf");
Agent myAgent=dbTarget.getAgent("B");
myAgent.runOnServer(noteID);
The called agent B could look like this
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
Database dbCurrent = agentContext.getCurrentDatabase();
Database dbSource = session.getDatabase(dbCurrent.Server, "ABC.nsf");
Document doc = dbSource.getDocumentByID(agentContext.getCurrentAgent().getParameterDocID())
This should work (if security is ok on the server).
As Paul mentioned in the comments security also means that the agent signer or web user (depending on the settings in agent A) has to have sufficient access to the target database AND the target server (if it is different).
If it does not work despite of correct security: Show us the exact error / trace.

May I suggest a different approach? If you don't need an immediate reply from the agent, as a return value in the code, why don't you send the other database a special mail? Create a mail agent (triggered after new mail has been received), at the sender side create a NotesDocument object, add the values you need to reference the document you want the agent to work on, like the name of the server, the replicaId of the database, and the uniqueId. The agent receives the mail and inspects the fields for what it's supposed to do. The receiving database should be mentioned in the N&A book as Mail-in database.
Advantages are manifold: no hassle with rights, a clear interface, no need to open the other database, the agent is executed by the agent manager at a convenient time, you can easily add more functionality the same way, etc.

Related

send email to generic ID in lotus notes using notesFactory in java

Their is a requirement in a project to send emails from java application through lotus notes.
Note: the domino server is installed on client server.
Currently i am able to send email using notesFactory on my local machine.using notes.jar file
Which accesses the user by .nsf by its password.
I.e creating secure connection by password.
And gtting database object by calling
Session.getdatabase(null,"user.nsf")
Its perfectly working.
But for some types of emails the client have shared a generic id...(link) over an email... By clicking on that link the generic mail box opens under active user. In separate tab... Through which we can send emails.
But have not shared their .nsf path or id or password.
It directly opens by clicking on that link.
Now i want to access that generic id in notesfactory session
I tried to keep open that id and then running my code...but still it sends email through active user itself.
And client is not ready to share the id and password details of that user. Not the id file is getting generated in our local machine.
Is their any way to send emails through that id?
If anyone want code i am using..ill share.
But for some types of emails the client have shared a generic
id...(link) over an email... By clicking on that link the generic mail
box opens under active user. In separate tab... Through which we can
send emails.
That does not sound like a "shared id", it sounds more like a mail database with the ACL set to give a group of users access.
When you send an email from within Notes (no matter if it is through the UI or through code), the actual logged in user is used as the sender. It is intentionally by design, to prevent users from spoofing the sender.
There is an unsupported way to fake the sender address, by dropping the email directly into mail.box, but that should only be done by someone know what they are doing.
I wrote a script library several years ago, intended to help sending emails. It includes the ability to set the sender address. You can find it on my blog, it's free to use. But I would not recommend you using it without first understanding what the code is doing.
Here is the relevant part of the code:
Set mailbox = New NotesDatabase(mailservername,"mail.box")
If mailbox.Isopen = False Then
Print "mail.box on " & mailservername & " could not be opened"
Exit Sub
End If
Set me.maildoc = New NotesDocument(mailbox)
Call me.maildoc.ReplaceItemValue("Form","Memo")
Set me.body = New NotesRichTextItem(maildoc,"Body")
Call maildoc.ReplaceItemValue("Principal", me.p_principal)
' If principal is set, we want to fix so mail looks like
' it is coming from that address, need to set these fields
Call maildoc.ReplaceItemValue("From", me.p_principal)
Call maildoc.ReplaceItemValue("Sender", me.p_principal)
Call maildoc.ReplaceItemValue("ReplyTo", me.p_principal)
Call maildoc.ReplaceItemValue("SMTPOriginator", me.p_principal)
Call maildoc.ReplaceItemValue("PostedDate",Now())
If me.p_principal<>"" Then
Call maildoc.Save(True,False) ' Save in mail.box
Else
Call maildoc.Send(True) ' Send mail normally
End If
You use the Principal field to set the sender address.

Different view content when accessing a Lotus Domino server

When I run the following Java code on a Lotus Domino server, I get different results depending on where the code runs.
private void doViewStuff(Session session, PrintStream out) throws NotesException {
Database db = session.getDatabase(null, "myDatabase.nsf");
View view = db.getView("myViewName");
Document doc = view.getFirstDocument();
while (doc != null) {
out.println("doc: " + doc.getUniversalID());
doc = view.getNextDocument(doc);
}
ViewEntryCollection entries = view.getAllEntries();
ViewEntry entry = entries.getFirstEntry();
while (entry != null) {
System.out.println("entry: " + entry.getColumnValues());
entry = entries.getNextEntry(entry);
}
}
When I run the code on the server as a Java agent, there are 37235 documents in the view.
When I run the code in a standalone client, there are only 37217 documents in the view, and the code is much, much slower.
Details and execution environment:
The server version is 8.5.3, the NCSO.jar I used for the client has SHA-1 d879f8992aae49a06769a564217633a9e0fbd1b6.
The database myDatabase.nsf contains about 150000 documents, each with a file attachment.
The missing documents do not appear in a block, they appear between index 10000 and 20000.
In both cases the code runs as the same user account.
What might be the reason that 18 of the documents cannot be found?
Update and Clarification
Upon further inspection, it turned out that I had indeed run the code with different user accounts, and that the inaccessible document had some Reader Names fields.
On the server I had this configuration, although I configured the agent to "Run on behalf of" CN=User Name/O=domain. It didn't matter whether I ran the agent from the Domino Console or via HTTP:
effectiveUserName=CN=User Name/O=domain
commonUserName=domino01
userName=CN=domino01/O=domain
On the client I had this configuration:
effectiveUserName=[NotesException: Not implemented]
commonUserName=User Name
userName=User Name/O=domain
And that was even though I used this code in the client:
Session session = NotesFactory.createSession("127.0.0.1", "User Name", "password");
You say that in both cases the code runs as the same user account, so I want to trust that this is true. I presume, therefore, that you have ruled out Reader Names fields as cause of the discrepancy.
In that case, have you checked the IsValid() property of the ViewEntry objects when you process them in the agent running on the server? Perhaps the NCSO.jar implementation that you are using for the client-side code is filtering out the objects where IsValid() would return false.

Account gets locked every time while trying to access via the V1APIConnector

I am trying to access the VersionOne data using the V1APIConnector. I can verify that I am using the correct data and meta URLs. I also have the correct domain/username and password.
But everytime I execute the below code, I get an Authentication error saying username/password is invalid and my account gets locked.
Once I unlocked my account, I tried again and the account was locked again. I am the V1 Administrator so I have the permissions.
Our VersionOne instance uses Windows Integrated Auththentication. Also my username is in the format -mydomain/myusername
Is there any different way to pass the credentials? Since my account is getting locked, it must mean at least the domain and the username are being passed correctly. Any Ideas?
V1APIConnector dataConnector = new V1APIConnector( _dataUrl, _username, _password);
V1APIConnector metaConnector = new V1APIConnector( _metaUrl );
IMetaModel metaModel = new MetaModel(metaConnector);
IServices services = new Services(metaModel, dataConnector);
System.out.println("Creating query");
IAssetType defectType = metaModel.getAssetType("Defect");
Query query = new Query(defectType);
IAttributeDefinition nameAttribute = defectType.getAttributeDefinition("Name");
query.getSelection().add(nameAttribute);
query.getPaging().setPageSize(3);
query.getPaging().setStart(0);
System.out.println("Retrieve from query");
QueryResult result = services.retrieve(query);
The Java.SDK ignores the username and password parameters of the V1APIConnector constructor when attempting to connect to a Windows Integrated instance, and instead uses the domain credentials that it is running under. If you are logged into your machine as "MyDomain\MyUsername" then that is the credentials that it will use. It does not support supplying the credentials of another account.
Note that there must also exist a VersionOne member account with the username set to "MyDomain\MyUsername" to successfully authenticate.
VersionOne locks accounts only when your license has expired, and if that happens, only the system administrator (Member:20) will remain active. In addition, administrators can deactivate accounts manually.

XStorable storeToURL and WebDav

I have seen multiple threads regarding the use of XStorable.storeToURL and vnd.sun.star.webdav://domain:8080//path/to/document_library to save OO documents to a webdav library folder. However, I have not seen a posting where someone has successfully used this in Java. While the use of the UCB vnd.sun.star.webdav://domain:8080//path/to/document_library/doc.odt works when using the File, Save menu options within OO Writer, I am prompted for a username and password. Supplying user and password via vnd.sun.star.webdav://user:password#domain:8080/ has not worked for me. I need to use this method from within a Java class to save a OO document. Has anyone had success using the following or something similar?
xStorable.storeToURL("vnd.sun.star.webdav://domain:8080/path/to/document_library/doc.odt", storeProps)
In the OO Developer's Guide, there is a paragraph regarding WebDav authentication:
DAV resources that require authentication are accessed using the interaction handler mechanism of the UCB. The DAV content calls an interaction handler supplied by the client to let it handle an authentication request. The implementation of the interaction handler collects the user name or password from a location, for example, a login dialog, and supplies this data as an interaction response.
Maybe this is related to the issue? If so, how to use an interaction handler for the authentication when trying to storeToURL via webdav?
Adding InteractionHandler was the issue. With this added, documents can be saved via storeToURL and passing the handler in as an argument:
String oooExeFolder = "C:/OpenOffice/program";
XComponentContext xLocalContext = BootstrapSocketConnector.bootstrap(oooExeFolder);
Object serviceManager = xLocalServiceManager.createInstanceWithContext("com.sun.star.task.InteractionHandler", xLocalContext);
XInteractionHandler xHandler = (XInteractionHandler)UnoRuntime.queryInterface( XInteractionHandler.class, serviceManager);
PropertyValue[] storeProps = new PropertyValue[1];
storeProps[0] = new PropertyValue();
storeProps[0].Name = "InteractionHandler";
storeProps[0].Value = xHandler;
xStorable.storeToURL("vnd.sun.star.webdav://domain:8080/path/to/document_library/doc.odt", storeProps);

How to read LDAP password policy in Java

Can i read user password policy from LDAP, like when it expires or more details like password strength (minimal length etc.) ? I need these information so I can use the same policy for users kept in my database. My java application require that users from the database have to be synchronized with domain.
If you want to get the password policy through LDAP queries try this
without PSO policy in your current domain
String searchDomain= "DC=company,DC=ORG";
String ldapQuery = "(&(objectClass=domainDNS))";
String ldapAttribute = "maxPwdAge";
If you use a PSO policy try this code
String domainLookupString = "CN=UsersPSO,CN=Password Settings Container,CN=System,DC=company,DC=ORG";
String ldapFilterString = "(&(objectClass=msDS-PasswordSettings))";
String ldapAttribute = "msDS-MaximumPasswordAge"
Usually, there are at least three different things that are of concern in these circumstances.
Account status, which includes such information as is the account locked, expired or disabled.
The account "status" is typically reflected on the MMC Account Tab.
We put some information on our wiki about the LDAP values at:
http://ldapwiki.willeke.com/wiki/Active%20Directory%20Account%20Lockout
and
http://ldapwiki.willeke.com/wiki/MMC%20Account%20Tab
Password status, is the password expired.
Unfortunately, the attributes that reflect the status of these conditions are not reflected in AD in real time. Some are only updated when a user attempts to authenticate. (either successfully or un-successfully).
-jim
Yes you can, with JNDI. You have to read the value of the pwdPolicySubentry operational attribute from the user's Context. This gives you the DN of the pwdPolicy object, which you then lookup as a Context with attributes, and get all the attributes starting with 'pwd'. However if the user has the default password policy you will have to look at your LDAP server configuration to find its DN. In OpenLDAP this is in slapd.conf in the ppolicy_default line in the 'overlay ppolicy' directives block.
It depends the underlying LDAP server.
For instance, if you are using Microsoft Active Directory, a user entry will have an attribute called accountExpires which is the date the account expires.
Active Directory also have a user attribute called userAccountControl which is a bit-mask specifying various account related states. For instance, if bit 24 is set, that means that the password has expired (userAccountControl & 0x800000 != 0). Bit 2 is "account disabled" etc. Read more at http://support.microsoft.com/kb/305144.
For other LDAP servers (OpenLDAP, ApacheDS, etc, etc) you'll have to look into the documentation.

Categories

Resources