0

I'm writing an integration API in Java for IBM Domino 10, I want to perform resource (room) reservations, fetch and update them from an external source. So far, I successfully created an entry in current user's calendar (current session) and the reservation is also successfull, however I want to create reservations as certain users (personification), since only one user is configured to use my API database. So the main user is used to do everything, but I'd like to pass him the credentials of other users and he should create the events & reservations in their calendars. I can verify if an user exists & if his password is correct, but I don't know how could I open his calendar because it's session based.

My current code:

        Database mdb = session.getDbDirectory(session.getServerName()).openMailDatabase();
        NotesCalendar cal = session.getCalendar(mdb);
        java.text.SimpleDateFormat datefmt = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
        String dStart = datefmt.format(dtStart);
        String dEnd = datefmt.format(dtEnd);

        Name nnOrganizer = session.createName(session.getEffectiveUserName());

        String iCalEntry = "BEGIN:VCALENDAR\n" +
            "PRODID:-//Test//Reservation API//EN\n" +
            "VERSION:2.0\n" +
            "BEGIN:VEVENT\n" +
            "DTSTART:" + dStart + "\n" +
            "DTEND:" + dEnd + "\n" +

            "SUMMARY:Sample Meeting\n" +
            "DESCRIPTION:TEST\n" +
            "ORGANIZER;CN=admin/O=Corp:mailto:test@test.test\n" +
            "ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;" + nnOrganizer.getCanonical() + ";RSVP=false:mailto:test@test.test\n" +
            "ATTENDEE;CUTYPE=ROOM;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;" + nnResource.getCanonical() + ";RSVP=true:mailto:room@test.test\n" +
            "END:VEVENT\n" +
            "END:VCALENDAR\n";

        NotesCalendarEntry entry = cal.createEntry(iCalEntry);
        System.out.println("calendar uid " + entry.getUID());

How could I make this work with any user I want? So it's not using session.getCalendar() but something else, so I could create an entry in another user's calendar.

Also, how can I programatically get the organizer's & room's email addresses? As for now, they are hardcoded. I know I could do a directory lookup, but sometimes the email (internet address) isn't configured, and lookupNames returns nothing. Notes client somehow bypasses that and creates an email like Name_Surname/server@Corp, is it enough?

Edit I achieved what I wanted by using the REST Service (CustomServiceBean) and NotesCalendar for creating/updating/deleting reservations, paired with direct document access to check for conflicts and read detailed room & reservation data. Everything works fine so far, reservations are visible in both user's calendar and the dtabase. However when I re-installed the server from scratch and added the database with rest service, I couldn't access the api with my default admin user (403 forbidden, You are forbidden to perform this operation ) server logs: HTTP JVM: CLFAD0229E: Security exception occurred servicing request for: /db.nsf/services.xsp/api - HTTP Code: 403. For more detailed information, please consult error-log-0.xml

When I added the admin user to Configuration->Current Server Document->Security->Sign or run unrestricted methods and operations, it starts working correctly, even when accessing the API with newly registered users (that weren't assigned any groups, permissions, nothing at all just an internet password & address and they were created by the admin account) Will this work correctly? I need to access the API from accounts of normal users, because I need to create entries in user's calendars.

AJ Cole
  • 169
  • 2
  • 13
  • Notes does support impersonation, and passing credentials around is a bad idea. The good idea, though, is hard to implement. That's because, to the best of my knowledge, Notes/Domino only allows impersonation when the code is running as a server task. Also, as far as I know, the server task has to be written in C in order to make use of the hNames argument to NSFDbOpenExteneded, as the higher-level APIs don't expose this capability. Also, the server where the task runs has to be set up as 'Trusted' by the home servers of the databases that you are accessing. – Richard Schwartz Mar 19 '19 at 02:04
  • An approach you can take, if you insist on passing around credentials, is to take advantage of a server task that already supports impersonation. I'm referring the the Domino web server task. If your server is running nhttp and it supports basic authentication, pass around web user credentials, you can send an HTTP request that invokes an agent that is configured with the "Run as Web User" option and use the approprirate credentials in the basic authentication header. The agent will run the actual code that accesses the calendar. But I repeat: passing credentials around is a bad idea. – Richard Schwartz Mar 19 '19 at 02:11
  • The request with the credentials will be made from my "indirect" server directly to the Domino server, so it's just like using the Calendar API, which requires authentication. Currently this Java code is running on the server as a CustomServiceBean, does it change anything? I could theorethically access the custom service using that particular user's credentials, but I'm not sure if it will work for every user? (I don't want to do any extra configuration for each user) – AJ Cole Mar 19 '19 at 07:36
  • I also need access to names.nsf (for $Rooms view) and the reservation database for $Reservations, I need to get all reservations in a particular room not only those in user's calendar – AJ Cole Mar 19 '19 at 07:37
  • @RichardSchwartz I kinda achieved what I wanted, however I have a small possible "problem". I edited my original post, I'd be glad if you checked it out. – AJ Cole Mar 20 '19 at 12:17
  • It's hard to follow your description of what's going on, but it sounds like you're not doing impersonation. You're just signing your code with an admin id and relying on that admin id having access to all the databases. That's safe as long as it is true that the admin id will have access to all the user mail databases, and as long as you're okay with the fact that the documents will appear to be created by the admin, not by the end users. – Richard Schwartz Mar 21 '19 at 02:02
  • @RichardSchwartz that's the way the original xpages java extension i'm basing on worked. Although afaik it was only accessed (through HTTP requests) by one specific user that was signed to the database. What I'm doing now, is accessing the service as specific users (sending their credentials in the Authorization HTTP header), the entries are created in their calendars just like I want, I'm just not sure if it will work always for every user? If I don't let admin "run unrestricted.." then noone can acccess, if I enter just him, every other user (on my local server) can access. – AJ Cole Mar 21 '19 at 07:44
  • The "run unrestricted" setting applies to the identity that the code is running on. With agents, that depends on the security settings on the agent. I don't know enough about your runtime context to know what it will be for your runtime context, but if you look at Session.UserName vs Session.EffectiveUserName, that should be enough to tell you. StackOverflow strongly discourages the use of comment threads for extended discussions, so I'm going to leave it at that. It's a bit disappointing that nobody else has answered, but the question is a bit wider in scope than most. – Richard Schwartz Mar 21 '19 at 12:39

0 Answers0