Office365 API - Admin accessing another users/room's calendar events
Asked Answered
Z

2

6

By hitting this request: https://outlook.office365.com/api/v1.0/users/[email protected]/events in a browser I can enter my admin username and password and get Calendar Events for that specific room. However when I try making this call from a native app with the admin authenticated I get this response: reason="The call should access the mailbox specified in the oauth token.";error_category="invalid_grant" How can I get calendar events for a specific room authenticated as the admin?

Zellazelle answered 2/6, 2015 at 11:6 Comment(1)
see the Java EWS API example answer below if you're running a Java web serverBlaineblainey
I
6

At present we only allow access to mail, calendar and contacts belonging to the authenticated user. So, your scenario of an admin accessing the conf. room calendar is not supported at this time. Access to resources belonging to other users e.g. conf. room calendar is on our roadmap to support but we don't yet have a timeframe to share with you.

In the meantime, you have two options.

Option #1: If you are able to run the app on a server, you can build a service app that requires admin consent, but is authorized to access any mailbox in the Office 365 tenant. You will need to make your native app talk to the app running on the server. See this blog for more details.

Option #2: You can use our Exchange Web Services SOAP API to implement your scenario. See Office 365 shared calendars for more details on this option and relevant links.

Irade answered 2/6, 2015 at 12:37 Comment(21)
Unfortunately the ews-java-api library does not work well on Android, it has un-resolved /missing jar files as referenced in this question: #29265799Zellazelle
There are third-party client APIs (JWebServices for Exchange ) or you can submit the requests and handle the responses yourself.Folly
@MichaelMainer-MSFT, Thank you, got it to work using JWebServices.Zellazelle
@Zellazelle - to be clear, you're saying that the /api/v1.0/user/[email protected]/events approach will not allow access to another users calendar, no matter what level of permissions the authenticated user has? IE, if the authenticated user is a Global Admin, and the app config in Azure has the 'Read User Calendars' permission, it still won't work???Narcissus
@Narcissus Yes, today to access any mailbox, you need to use client credential flow. We will support for access to other user mailboxes by end of the year.Irade
@VenkatAyyadevara-MSFT Got it, thanks. I see that Basic Auth works. I was just hoping we could go more secure with OAuth. Looking forward to news later this year.Narcissus
Is this working now? I'm using v2 and need to access read+write all meeting rooms calendar.. ThanksPoddy
Not yet, but we are working on it. We are aiming for it to be available by end of June 2016.Irade
@VenkatAyyadevara-MSFT Hi, do you confirm that this feature will be available at the end of June? I mean the possibility for an administrator to access other users' calendars by the APIs.Cauda
@Cauda Sorry, we are still working on this, and it won't be available by end of this month. Will let you know once we have an updated date.Irade
@VenkatAyyadevara-MSFT Is there a date planned yet? :) ThanksPoddy
@GaSacchi Not yet, work is still in progress. Will update as soon as I know ETA.Irade
@everyone: MS still isn't done with the v2, but there is a working example below using the Java EWS API.Blaineblainey
@VenkatAyyadevara-MSFT Can you please inform us when this feature will be available?Formerly
@VenkatAyyadevara-MSFT How this can take so long? something like /v2.0/resources/events would be also awesome :PNesbitt
@Nesbitt I understand the frustration. We are currently in validation phase. So, hopefully not too long.Irade
@aperu Yes, I will update my answer to this question when the feature is available.Irade
@VenkatAyyadevara-MSFT Is this still not possible?Asaasabi
@VenkatAyyadevara-MSFT anything?Failing
@VenkatAyyadevara-MSFT 2015 - 2018 still does not workRibwort
I kept promising this feature to my boss and got fired.. :pPoddy
B
4

This small PLUG-N-COMPILE-RUN (woo-hoo!) Java Class should demo getting to a room resource user calendar of events. The Azure V2.0 REST API is not currently allowing one to do so. Make sure that the auth-user that authenticates to the Exchange service is a "delegate" to (or of) the room resource user calendar whose events you want to retrieve. Your Exchange/Office365 admin might need to set that up for you. I grabbed the Java EWS API here: Index of /maven2/com/microsoft/ews-java-api/ews-java-api/2.0/ ews-java-api-2.0.jar and the javadoc.jar which was a great reference. You can also use Maven, Gradle or other methods to integrate the API into your code if you go to the Github repo: https://github.com/OfficeDev/ews-java-api. The Getting Started Guide is...well...words escape me (for good reason). Put it this way, you'd better use your search engine a bit in order to figure out how to do other stuff! And looking through the classes in the Javadoc helped me a good deal. Enough blah-blah-blah... On to the code: (oh, I included all of the imports! I always hate it when I get a sample snippet of code and I have to go hunting and pecking for the imports. I still leave it to you to get hooked up the the actual libraries, though! You're not in code-diapers anymore, if you can get this far! ;-)

package com.on.and.play

import java.net.URI;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.text.DateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat

import microsoft.exchange.webservices.data.core.service.item.Appointment;
import microsoft.exchange.webservices.data.core.service.schema.AppointmentSchema;
import microsoft.exchange.webservices.data.core.service.folder.CalendarFolder;
import microsoft.exchange.webservices.data.search.CalendarView;
import microsoft.exchange.webservices.data.credential.ExchangeCredentials;
import microsoft.exchange.webservices.data.core.ExchangeService;
import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
import microsoft.exchange.webservices.data.search.FindItemsResults;
import microsoft.exchange.webservices.data.property.complex.FolderId;
import microsoft.exchange.webservices.data.search.FolderView
import microsoft.exchange.webservices.data.core.service.schema.FolderSchema
import microsoft.exchange.webservices.data.search.FindFoldersResults
import microsoft.exchange.webservices.data.search.filter.SearchFilter
import microsoft.exchange.webservices.data.core.enumeration.search.FolderTraversal
import microsoft.exchange.webservices.data.core.service.item.Item;
import microsoft.exchange.webservices.data.core.service.schema.ItemSchema;
import microsoft.exchange.webservices.data.property.complex.Mailbox
import microsoft.exchange.webservices.data.search.ItemView;
import microsoft.exchange.webservices.data.core.PropertySet;
import microsoft.exchange.webservices.data.property.definition.PropertyDefinition
import microsoft.exchange.webservices.data.credential.WebCredentials;
import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName;
import microsoft.exchange.webservices.data.core.enumeration.property.BasePropertySet;
import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException
import java.net.URI;

class MyTestService {
  public List getRoomCalendar() {       
    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    // replace [email protected] with a real email address that is
    // a delegate of [email protected]. Your exchange admin may  
    // need to set that up for you. 
    ExchangeCredentials credentials 
        = new WebCredentials("[email protected]",
                             "their_plain_text_password_God_bless_Microsoft");
    service.setCredentials(credentials);
    service.setUrl(new URI("https://outlook.office365.com/EWS/Exchange.asmx"));
    // service.autodiscoverUrl("[email protected]", );
    FolderView fv = new FolderView(100);
    fv.setTraversal(FolderTraversal.Deep);
    // replace [email protected] with your resource's email address 
    FolderId confRoomFolderId = new FolderId(WellKnownFolderName.Calendar, 
                                             new Mailbox("[email protected]"));
    List apntmtDataList = new ArrayList();          
    Calendar now = Calendar.getInstance();
    Date startDate = Calendar.getInstance().getTime();
    now.add(Calendar.DATE, 30);
    Date endDate = now.getTime();
    try {
      CalendarFolder calendarFolder = CalendarFolder.bind(service, confRoomFolderId);
      CalendarView cView = new CalendarView(startDate, endDate, 5);
      cView.setPropertySet(new PropertySet(AppointmentSchema.Subject, 
                                           AppointmentSchema.Start,
                                           AppointmentSchema.End));
      // we can set other properties as well depending upon our need.
      FindItemsResults appointments = calendarFolder.findAppointments(cView);
      List<Appointment> appList = appointments.getItems();
      for (Appointment appointment : appList) {
        Map appointmentData = new HashMap();
        appointmentData = readAppointment(appointment);
        apntmtDataList.add(appointmentData);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return apntmtDataList;
  } 

  public Map readAppointment(Appointment appointment) {
    Map appointmentData = new HashMap();
    try {
      DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
      appointmentData.put("appointmentItemId", appointment.getId().toString());
      appointmentData.put("appointmentSubject", appointment.getSubject());
      appointmentData.put("appointmentStartTime", df.format(appointment.getStart()));
      appointmentData.put("appointmentEndTime", df.format(appointment.getEnd()));
    } catch (ServiceLocalException e) {
      e.printStackTrace();
    }       
    return appointmentData;
  }
}
Blaineblainey answered 19/8, 2016 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.