Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Spring Social support for Microsoft Graph (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhijunZhao committed Aug 17, 2017
1 parent 3be5eec commit 3d92eb6
Show file tree
Hide file tree
Showing 35 changed files with 1,964 additions and 89 deletions.
4 changes: 3 additions & 1 deletion common/azure-spring-boot-starter-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@
<show>private</show>
<failOnError>false</failOnError>
<sourceFileExcludes>
<exclude>com/microsoft/azure/spring/data/documentdb/core/mapping/BasicDocumentDbPersistentProperty.java</exclude>
<exclude>
com/microsoft/azure/spring/data/documentdb/core/mapping/BasicDocumentDbPersistentProperty.java
</exclude>
</sourceFileExcludes>
</configuration>
<executions>
Expand Down
1 change: 1 addition & 0 deletions common/config/findbugs-exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
<Bug pattern="NP_NONNULL_PARAM_VIOLATION"/>
<Bug pattern="Unwritten field"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>
<Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD"/>
</FindBugsFilter>
15 changes: 10 additions & 5 deletions microsoft-graph/microsoft-graph-spring-boot-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
Expand All @@ -67,5 +62,15 @@
<groupId>com.microsoft.azure</groupId>
<artifactId>spring-social-microsoft-graph</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/
package com.microsoft.azure.autoconfigure.msgraph;

public class Constants {
public static final String APP_ID_PROPERTY = "spring.social.microsoft.app-id";
public static final String APP_ID = "123456789-acb1-4d0b-a13b-1a70ac85d8bf";
public static final String APP_SECRET_PROPERTY = "spring.social.microsoft.app-secret";
public static final String APP_SECRET = "1234mAocWmbvawgg4hyRTZ8";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.autoconfigure.msgraph;

import com.microsoft.azure.msgraph.api.Microsoft;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import static org.assertj.core.api.Java6Assertions.assertThat;

public class MicrosoftAutoConfigurationTest {
@Test
public void canAutowire() {
System.setProperty(Constants.APP_ID_PROPERTY, Constants.APP_ID);
System.setProperty(Constants.APP_SECRET_PROPERTY, Constants.APP_SECRET);

try (AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext()) {
context.register(MicrosoftAutoConfiguration.class);
context.register(SocialWebAutoConfiguration.class);
context.refresh();
Assertions.assertThat(context.getBean(Microsoft.class)).isNotNull();
}

System.clearProperty(Constants.APP_ID_PROPERTY);
System.clearProperty(Constants.APP_SECRET_PROPERTY);
}

@Test
public void cannotAutowire() {
try (AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext()) {
context.register(MicrosoftAutoConfiguration.class);
context.register(SocialWebAutoConfiguration.class);
context.refresh();

Microsoft microsoft = null;
try {
microsoft = context.getBean(Microsoft.class);
} catch (Exception e) {
assertThat(e.getMessage()).contains("No qualifying bean of type 'com.microsoft.azure." +
"msgraph.api.Microsoft' available");
}
assertThat(microsoft).isNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.autoconfigure.msgraph;

import org.junit.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;

import static org.assertj.core.api.Assertions.assertThat;

public class MicrosoftPropertiesTest {
@Test
public void canSetProperties() {
System.setProperty(Constants.APP_ID_PROPERTY, Constants.APP_ID);
System.setProperty(Constants.APP_SECRET_PROPERTY, Constants.APP_SECRET);

try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
context.register(Config.class);
context.refresh();
final MicrosoftProperties properties = context.getBean(MicrosoftProperties.class);

assertThat(properties.getAppId()).isEqualTo(Constants.APP_ID);
assertThat(properties.getAppSecret()).isEqualTo(Constants.APP_SECRET);
}

System.clearProperty(Constants.APP_ID_PROPERTY);
System.clearProperty(Constants.APP_SECRET_PROPERTY);
}

@Configuration
@EnableConfigurationProperties(MicrosoftProperties.class)
static class Config {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ Go to [Application Registration Portal](https://apps.dev.microsoft.com/#/appList
```
mvn package
java -jar target/microsoft-graph-spring-social-starter-sample-0.0.1-SNAPSHOT.jar
```
```

### Make your own REST API call

This starter implements a small subset of Objects/APIs available via Microsoft Graph (GET /me, POST /me/sendMail, GET /me/messages). In addition, it demonstrates how to make custom REST API calls (see function `getContacts` in `HelloController.java` as an example). Please check the detailed [document](https://developer.microsoft.com/en-us/graph/docs/concepts/overview) for more details about Microsoft Graph.
After reading the document, you should be aware of the exact REST API and what objects you should prepare or expect from the REST API call.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import sample.microsoft.graph.custom.Contacts;

import java.net.URI;

@Controller
@RequestMapping("/")
public class HelloController {

private Microsoft microsoft;
private ConnectionRepository connectionRepository;

Expand All @@ -25,8 +26,8 @@ public HelloController(Microsoft microsoft, ConnectionRepository connectionRepos
this.connectionRepository = connectionRepository;
}

@GetMapping
public String helloFacebook(Model model) {
@RequestMapping("/")
public String helloMicrosoft(Model model) {
if (connectionRepository.findPrimaryConnection(Microsoft.class) == null) {
return "redirect:/connect/microsoft";
}
Expand All @@ -36,4 +37,17 @@ public String helloFacebook(Model model) {
return "hello";
}

@RequestMapping("/contacts")
public String getContacts(Model model) {
if (connectionRepository.findPrimaryConnection(Microsoft.class) == null) {
return "redirect:/connect/microsoft";
}

final RestTemplate restTemplate = microsoft.customOperations().getRestTemplate();
final URI uri = microsoft.customOperations().getGraphAPIURI("me/contacts");
final Contacts contacts = restTemplate.getForObject(uri, Contacts.class);
model.addAttribute("contacts", contacts.getContacts());

return "contacts";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package sample.microsoft.graph.custom;

// Please be noted this is not a complete representation of the JSON object returned by Microsoft Graph.
public class Contact {

private String displayName;
private String mobilePhone;

/**
* The Display Name.
*/
public String getDisplayName() {
return displayName;
}

public void setDisplayName(String displayName) {
this.displayName = displayName;
}

/**
* The Mobile Phone.
*/
public String getMobilePhone() {
return mobilePhone;
}

public void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package sample.microsoft.graph.custom;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Contacts {
@JsonProperty("value")
private java.util.List<Contact> contacts;

@JsonProperty("@odata.nextLink")
private String nextLink;

public java.util.List<Contact> getContacts() {
return contacts;
}

public void setContacts(java.util.List<Contact> contacts) {
this.contacts = contacts;
}

/**
* The url to the next page of this collection, or null
*/
public String getNextLink() {
return nextLink;
}

public void setNextLink(String nextLink) {
this.nextLink = nextLink;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<h3>Connect to Microsoft Graph</h3>

<form action="/connect/microsoft" method="POST">
<input type="hidden" name="scope" value="User.Read"/>
<input type="hidden" name="scope" value="User.Read Contacts.Read"/>
<div class="formInfo">
<p>You aren't connected to Microsoft yet. Click the button to connect this application with your Microsoft
account.</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<html>
<head>
<title>Hello Microsoft Graph</title>
</head>
<body>
<table>
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
<tr th:each="contact : ${contacts}">
<td th:text="${contact.getDisplayName()}"/>
<td th:text="${contact.getMobilePhone()}"/>
</tr>
</table>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
<th>User Principal Name</th>
<td th:text="${user.userPrincipalName}"/>
</tr>
<tr>
<th>Contacts</th>
<td><a href="/contacts.html">click here</a></td>
</tr>
</table>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.msgraph.api;

/**
* The Enum Body Type.
*/
public enum BodyType {
/**
* text
*/
text,
/**
* html
*/
html,
/**
* For BodyType values that were not expected from the service
*/
unexpectedValue
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for
* license information.
*/

package com.microsoft.azure.msgraph.api;

import org.springframework.web.client.RestTemplate;

import java.net.URI;

public interface CustomOperations {
public RestTemplate getRestTemplate();

public URI getGraphAPIURI(String relativePath);
}
Loading

0 comments on commit 3d92eb6

Please sign in to comment.