diff --git a/README.md b/README.md index 8cf3ceb..ba6debb 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,11 @@ In this lab you will create a console application using the Microsoft Authentica - [Java Microsoft Graph tutorial](https://docs.microsoft.com/graph/tutorials/java) -## Demos - -The [demos](./demos) directory in this repository contains copies of the project that correspond to completing individual sections of the tutorial. If you just want to demo a particular section of the tutorial, you can start with the version from the previous section. - -- [01-create-app](demos/01-create-app): Completed [Create a Java console app](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=1) -- [02-add-aad-auth](demos/02-add-aad-auth): Completed [Add Azure AD authentication](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=3) -- [03-add-msgraph](demos/03-add-msgraph): Completed [Get calendar data](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=4) - ## Completed sample If you just want the completed sample generated by following this lab, you can find it here. -- [Completed project](demos/03-add-msgraph) +- [Completed project](demo) ## Disclaimer diff --git a/demos/03-add-msgraph/README.md b/demo/README.md similarity index 85% rename from demos/03-add-msgraph/README.md rename to demo/README.md index b09177c..e9adb2f 100644 --- a/demos/03-add-msgraph/README.md +++ b/demo/README.md @@ -4,7 +4,7 @@ To run the completed project in this folder, you need the following: -- [Java SE Development Kit (JDK)](https://java.com/en/download/faq/develop.xml) and [Maven](https://maven.apache.org/) installed on your development machine. If you do not have the JDK or Maven, visit the previous links for download options. (**Note:** This tutorial was written with OpenJDK version 12.0.1 and Maven 3.6.1. The steps in this guide may work with other versions, but that has not been tested.) +- [Java SE Development Kit (JDK)](https://java.com/en/download/faq/develop.xml) and [Gradle](https://gradle.org/) installed on your development machine. If you do not have the JDK or Gradle, visit the previous links for download options. (**Note:** This tutorial was written with OpenJDK version 14.0.0.36 and Gradle 6.3. The steps in this guide may work with other versions, but that has not been tested.) - A Microsoft work or school account. If you don't have a Microsoft account, you can [sign up for the Office 365 Developer Program](https://developer.microsoft.com/office/dev-program) to get a free Office 365 subscription. @@ -48,6 +48,5 @@ If you don't have a Microsoft account, you can [sign up for the Office 365 Devel In your command-line interface (CLI), navigate to the project directory and run the following commands. ```Shell -mvn package -java -cp target/graphtutorial-1.0-SNAPSHOT.jar com.contoso.App +./gradlew --console plain run ``` diff --git a/demo/graphtutorial/.gitattributes b/demo/graphtutorial/.gitattributes new file mode 100644 index 0000000..00a51af --- /dev/null +++ b/demo/graphtutorial/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf + diff --git a/demo/graphtutorial/.gitignore b/demo/graphtutorial/.gitignore new file mode 100644 index 0000000..1b6985c --- /dev/null +++ b/demo/graphtutorial/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/demo/graphtutorial/.project b/demo/graphtutorial/.project new file mode 100644 index 0000000..547c0f8 --- /dev/null +++ b/demo/graphtutorial/.project @@ -0,0 +1,17 @@ + + + graphtutorial_ + Project graphtutorial_ created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/demo/graphtutorial/.settings/org.eclipse.buildship.core.prefs b/demo/graphtutorial/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..e889521 --- /dev/null +++ b/demo/graphtutorial/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/demo/graphtutorial/build.gradle b/demo/graphtutorial/build.gradle new file mode 100644 index 0000000..adad73a --- /dev/null +++ b/demo/graphtutorial/build.gradle @@ -0,0 +1,45 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java project to get you started. + * For more details take a look at the Java Quickstart chapter in the Gradle + * User Manual available at https://docs.gradle.org/6.3/userguide/tutorial_java_projects.html + */ + +plugins { + // Apply the java plugin to add support for Java + id 'java' + + // Apply the application plugin to add support for building a CLI application. + id 'application' +} + +repositories { + // Use jcenter for resolving dependencies. + // You can declare any Maven/Ivy/file repository here. + jcenter() +} + +// +dependencies { + // This dependency is used by the application. + implementation 'com.google.guava:guava:28.2-jre' + + // Use JUnit test framework + testImplementation 'junit:junit:4.12' + implementation 'com.microsoft.azure:msal4j:1.4.0' + implementation 'com.microsoft.graph:microsoft-graph:1.6.0' + implementation 'org.slf4j:slf4j-nop:1.8.0-beta4' +} +// + +application { + // Define the main class for the application. + mainClassName = 'graphtutorial.App' +} + +// +run { + standardInput = System.in +} +// diff --git a/demo/graphtutorial/gradle/wrapper/gradle-wrapper.jar b/demo/graphtutorial/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..490fda8 Binary files /dev/null and b/demo/graphtutorial/gradle/wrapper/gradle-wrapper.jar differ diff --git a/demo/graphtutorial/gradle/wrapper/gradle-wrapper.properties b/demo/graphtutorial/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a4b4429 --- /dev/null +++ b/demo/graphtutorial/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/demo/graphtutorial/gradlew b/demo/graphtutorial/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/demo/graphtutorial/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/demo/graphtutorial/gradlew.bat b/demo/graphtutorial/gradlew.bat new file mode 100644 index 0000000..62bd9b9 --- /dev/null +++ b/demo/graphtutorial/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/demo/graphtutorial/settings.gradle b/demo/graphtutorial/settings.gradle new file mode 100644 index 0000000..2518738 --- /dev/null +++ b/demo/graphtutorial/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.3/userguide/multi_project_builds.html + */ + +rootProject.name = 'graphtutorial' diff --git a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/App.java b/demo/graphtutorial/src/main/java/graphtutorial/App.java similarity index 91% rename from demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/App.java rename to demo/graphtutorial/src/main/java/graphtutorial/App.java index 30f7b54..1b6da26 100644 --- a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/App.java +++ b/demo/graphtutorial/src/main/java/graphtutorial/App.java @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -package com.contoso; + +package graphtutorial; import java.io.IOException; import java.time.LocalDateTime; @@ -24,6 +25,7 @@ public static void main(String[] args) { System.out.println("Java Graph Tutorial"); System.out.println(); + // // Load OAuth settings final Properties oAuthProperties = new Properties(); try { @@ -35,6 +37,7 @@ public static void main(String[] args) { final String appId = oAuthProperties.getProperty("app.id"); final String[] appScopes = oAuthProperties.getProperty("app.scopes").split(","); + // // Get an access token Authentication.initialize(appId); @@ -84,6 +87,17 @@ public static void main(String[] args) { input.close(); } + // + private static String formatDateTimeTimeZone(DateTimeTimeZone date) { + LocalDateTime dateTime = LocalDateTime.parse(date.dateTime); + + return dateTime.format( + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)) + + " (" + date.timeZone + ")"; + } + // + + // private static void listCalendarEvents(String accessToken) { // Get the user's events List events = Graph.getEvents(accessToken); @@ -99,10 +113,5 @@ private static void listCalendarEvents(String accessToken) { System.out.println(); } - - private static String formatDateTimeTimeZone(DateTimeTimeZone date) { - LocalDateTime dateTime = LocalDateTime.parse(date.dateTime); - - return dateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)) + " (" + date.timeZone + ")"; - } -} + // +} \ No newline at end of file diff --git a/demos/02-add-aad-auth/graphtutorial/src/main/java/com/contoso/Authentication.java b/demo/graphtutorial/src/main/java/graphtutorial/Authentication.java similarity index 86% rename from demos/02-add-aad-auth/graphtutorial/src/main/java/com/contoso/Authentication.java rename to demo/graphtutorial/src/main/java/graphtutorial/Authentication.java index c0df4f6..d13a806 100644 --- a/demos/02-add-aad-auth/graphtutorial/src/main/java/com/contoso/Authentication.java +++ b/demo/graphtutorial/src/main/java/graphtutorial/Authentication.java @@ -1,8 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.contoso; +// Licensed under the MIT license. + +// +package graphtutorial; + import java.net.MalformedURLException; import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.function.Consumer; import com.microsoft.aad.msal4j.DeviceCode; @@ -15,7 +20,7 @@ */ public class Authentication { - private static String applicationId = null; + private static String applicationId; // Set authority to allow only organizational accounts // Device code flow only supports organizational accounts private final static String authority = "https://login.microsoftonline.com/common/"; @@ -32,12 +37,14 @@ public static String getUserAccessToken(String[] scopes) { Set scopeSet = Set.of(scopes); + ExecutorService pool = Executors.newFixedThreadPool(1); PublicClientApplication app; try { // Build the MSAL application object with // app ID and authority app = PublicClientApplication.builder(applicationId) .authority(authority) + .executorService(pool) .build(); } catch (MalformedURLException e) { return null; @@ -61,10 +68,13 @@ public static String getUserAccessToken(String[] scopes) { return null; }).join(); + pool.shutdown(); + if (result != null) { return result.accessToken(); } return null; } -} \ No newline at end of file +} +// \ No newline at end of file diff --git a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/Graph.java b/demo/graphtutorial/src/main/java/graphtutorial/Graph.java similarity index 95% rename from demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/Graph.java rename to demo/graphtutorial/src/main/java/graphtutorial/Graph.java index 16f8002..02e33a6 100644 --- a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/Graph.java +++ b/demo/graphtutorial/src/main/java/graphtutorial/Graph.java @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.contoso; +// Licensed under the MIT license. + +package graphtutorial; import java.util.LinkedList; import java.util.List; @@ -52,6 +53,7 @@ public static User getUser(String accessToken) { return me; } + // public static List getEvents(String accessToken) { ensureGraphClient(accessToken); @@ -70,4 +72,5 @@ public static List getEvents(String accessToken) { return eventPage.getCurrentPage(); } + // } \ No newline at end of file diff --git a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/SimpleAuthProvider.java b/demo/graphtutorial/src/main/java/graphtutorial/SimpleAuthProvider.java similarity index 84% rename from demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/SimpleAuthProvider.java rename to demo/graphtutorial/src/main/java/graphtutorial/SimpleAuthProvider.java index a373d74..2f03ec4 100644 --- a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/SimpleAuthProvider.java +++ b/demo/graphtutorial/src/main/java/graphtutorial/SimpleAuthProvider.java @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.contoso; +// Licensed under the MIT license. + +// +package graphtutorial; import com.microsoft.graph.authentication.IAuthenticationProvider; import com.microsoft.graph.http.IHttpRequest; @@ -21,4 +23,5 @@ public void authenticateRequest(IHttpRequest request) { // Add the access token in the Authorization header request.addHeader("Authorization", "Bearer " + accessToken); } -} \ No newline at end of file +} +// \ No newline at end of file diff --git a/demo/graphtutorial/src/main/resources/graphtutorial/oAuth.properties.example b/demo/graphtutorial/src/main/resources/graphtutorial/oAuth.properties.example new file mode 100644 index 0000000..a839af4 --- /dev/null +++ b/demo/graphtutorial/src/main/resources/graphtutorial/oAuth.properties.example @@ -0,0 +1,2 @@ +app.id=YOUR_APP_ID_HERE +app.scopes=User.Read,Calendars.Read diff --git a/demo/graphtutorial/src/test/java/graphtutorial/AppTest.java b/demo/graphtutorial/src/test/java/graphtutorial/AppTest.java new file mode 100644 index 0000000..9f25ac0 --- /dev/null +++ b/demo/graphtutorial/src/test/java/graphtutorial/AppTest.java @@ -0,0 +1,11 @@ +/* + * This Java source file was generated by the Gradle 'init' task. + */ +package graphtutorial; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class AppTest { + +} diff --git a/demos/01-create-app/README.md b/demos/01-create-app/README.md deleted file mode 100644 index c356e54..0000000 --- a/demos/01-create-app/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Completed module: Create a Java console app - -The version of the project in this directory reflects completing the tutorial up through [Create a Java console app](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=1). If you use this version of the project, you need to complete the rest of the tutorial starting at [Register the app in the portal](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=2). diff --git a/demos/01-create-app/graphtutorial/.classpath b/demos/01-create-app/graphtutorial/.classpath deleted file mode 100644 index c8a5e37..0000000 --- a/demos/01-create-app/graphtutorial/.classpath +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/01-create-app/graphtutorial/.factorypath b/demos/01-create-app/graphtutorial/.factorypath deleted file mode 100644 index 5e74494..0000000 --- a/demos/01-create-app/graphtutorial/.factorypath +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/01-create-app/graphtutorial/.project b/demos/01-create-app/graphtutorial/.project deleted file mode 100644 index 2fae9f9..0000000 --- a/demos/01-create-app/graphtutorial/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - graphtutorial - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/demos/01-create-app/graphtutorial/.settings/org.eclipse.core.resources.prefs b/demos/01-create-app/graphtutorial/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index f9fe345..0000000 --- a/demos/01-create-app/graphtutorial/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/test/java=UTF-8 -encoding/=UTF-8 diff --git a/demos/01-create-app/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs b/demos/01-create-app/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index 687ad91..0000000 --- a/demos/01-create-app/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=true -org.eclipse.jdt.apt.genSrcDir=target\\generated-sources\\annotations -org.eclipse.jdt.apt.genTestSrcDir=target\\generated-test-sources\\test-annotations diff --git a/demos/01-create-app/graphtutorial/.settings/org.eclipse.jdt.core.prefs b/demos/01-create-app/graphtutorial/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 399797f..0000000 --- a/demos/01-create-app/graphtutorial/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=12 -org.eclipse.jdt.core.compiler.compliance=12 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.processAnnotations=enabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=12 diff --git a/demos/01-create-app/graphtutorial/.settings/org.eclipse.m2e.core.prefs b/demos/01-create-app/graphtutorial/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/demos/01-create-app/graphtutorial/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/demos/01-create-app/graphtutorial/pom.xml b/demos/01-create-app/graphtutorial/pom.xml deleted file mode 100644 index 4e3e00d..0000000 --- a/demos/01-create-app/graphtutorial/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - 4.0.0 - - com.contoso - graphtutorial - 1.0-SNAPSHOT - - graphtutorial - - http://www.example.com - - - UTF-8 - 12 - 12 - - - - - - org.slf4j - slf4j-nop - 1.8.0-beta4 - - - - com.microsoft.graph - microsoft-graph - 1.6.0 - - - - com.microsoft.azure - msal4j - 1.1.0 - - - - junit - junit - 4.11 - test - - - - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - diff --git a/demos/01-create-app/graphtutorial/src/main/java/com/contoso/App.java b/demos/01-create-app/graphtutorial/src/main/java/com/contoso/App.java deleted file mode 100644 index 5597108..0000000 --- a/demos/01-create-app/graphtutorial/src/main/java/com/contoso/App.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.contoso; - -import java.util.InputMismatchException; -import java.util.Scanner; - -/** - * Graph Tutorial - * - */ -public class App { - public static void main(String[] args) { - System.out.println("Java Graph Tutorial"); - System.out.println(); - - Scanner input = new Scanner(System.in); - - int choice = -1; - - while (choice != 0) { - System.out.println("Please choose one of the following options:"); - System.out.println("0. Exit"); - System.out.println("1. Display access token"); - System.out.println("2. List calendar events"); - - try { - choice = input.nextInt(); - } catch (InputMismatchException ex) { - // Skip over non-integer input - input.nextLine(); - } - - // Process user choice - switch(choice) { - case 0: - // Exit the program - System.out.println("Goodbye..."); - break; - case 1: - // Display access token - break; - case 2: - // List the calendar - break; - default: - System.out.println("Invalid choice"); - } - } - - input.close(); - } -} diff --git a/demos/01-create-app/graphtutorial/src/test/java/com/contoso/AppTest.java b/demos/01-create-app/graphtutorial/src/test/java/com/contoso/AppTest.java deleted file mode 100644 index 6a9717e..0000000 --- a/demos/01-create-app/graphtutorial/src/test/java/com/contoso/AppTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.contoso; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -/** - * Unit test for simple App. - */ -public class AppTest -{ - /** - * Rigorous Test :-) - */ - @Test - public void shouldAnswerWithTrue() - { - assertTrue( true ); - } -} diff --git a/demos/02-add-aad-auth/README.md b/demos/02-add-aad-auth/README.md deleted file mode 100644 index baaf640..0000000 --- a/demos/02-add-aad-auth/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Completed module: Add Azure AD authentication - -The version of the project in this directory reflects completing the tutorial up through [Add Azure AD authentication](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=3). If you use this version of the project, you need to complete the rest of the tutorial starting at [Get calendar data](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=4). - -> **Note:** It is assumed that you have already registered an application in the app registration portal as specified in [Register the app in the portal](https://docs.microsoft.com/graph/tutorials/java?tutorial-step=2). You need to configure this version of the sample as follows: -> -> 1. Rename the `oAuth.properties.example` file to `oAuth.properties`. -> 1. Edit the `oAuth.properties` file and make the following changes. -> 1. Replace `YOUR_APP_ID_HERE` with the **Application Id** you got from the App Registration Portal. diff --git a/demos/02-add-aad-auth/graphtutorial/.classpath b/demos/02-add-aad-auth/graphtutorial/.classpath deleted file mode 100644 index afadaf6..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.classpath +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/02-add-aad-auth/graphtutorial/.factorypath b/demos/02-add-aad-auth/graphtutorial/.factorypath deleted file mode 100644 index 5e74494..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.factorypath +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/02-add-aad-auth/graphtutorial/.project b/demos/02-add-aad-auth/graphtutorial/.project deleted file mode 100644 index 2fae9f9..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - graphtutorial - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.core.resources.prefs b/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 839d647..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding/=UTF-8 diff --git a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs b/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index 687ad91..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=true -org.eclipse.jdt.apt.genSrcDir=target\\generated-sources\\annotations -org.eclipse.jdt.apt.genTestSrcDir=target\\generated-test-sources\\test-annotations diff --git a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.jdt.core.prefs b/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 399797f..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=12 -org.eclipse.jdt.core.compiler.compliance=12 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.processAnnotations=enabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=12 diff --git a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.m2e.core.prefs b/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/demos/02-add-aad-auth/graphtutorial/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/demos/02-add-aad-auth/graphtutorial/pom.xml b/demos/02-add-aad-auth/graphtutorial/pom.xml deleted file mode 100644 index 4e3e00d..0000000 --- a/demos/02-add-aad-auth/graphtutorial/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - 4.0.0 - - com.contoso - graphtutorial - 1.0-SNAPSHOT - - graphtutorial - - http://www.example.com - - - UTF-8 - 12 - 12 - - - - - - org.slf4j - slf4j-nop - 1.8.0-beta4 - - - - com.microsoft.graph - microsoft-graph - 1.6.0 - - - - com.microsoft.azure - msal4j - 1.1.0 - - - - junit - junit - 4.11 - test - - - - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - diff --git a/demos/02-add-aad-auth/graphtutorial/src/main/java/com/contoso/App.java b/demos/02-add-aad-auth/graphtutorial/src/main/java/com/contoso/App.java deleted file mode 100644 index b44dd8e..0000000 --- a/demos/02-add-aad-auth/graphtutorial/src/main/java/com/contoso/App.java +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.contoso; - -import java.io.IOException; -import java.util.InputMismatchException; -import java.util.Properties; -import java.util.Scanner; - -/** - * Graph Tutorial - * - */ -public class App { - public static void main(String[] args) { - System.out.println("Java Graph Tutorial"); - System.out.println(); - - // Load OAuth settings - final Properties oAuthProperties = new Properties(); - try { - oAuthProperties.load(App.class.getResourceAsStream("oAuth.properties")); - } catch (IOException e) { - System.out.println("Unable to read OAuth configuration. Make sure you have a properly formatted oAuth.properties file. See README for details."); - return; - } - - final String appId = oAuthProperties.getProperty("app.id"); - final String[] appScopes = oAuthProperties.getProperty("app.scopes").split(","); - - // Get an access token - Authentication.initialize(appId); - final String accessToken = Authentication.getUserAccessToken(appScopes); - - Scanner input = new Scanner(System.in); - - int choice = -1; - - while (choice != 0) { - System.out.println("Please choose one of the following options:"); - System.out.println("0. Exit"); - System.out.println("1. Display access token"); - System.out.println("2. List calendar events"); - - try { - choice = input.nextInt(); - } catch (InputMismatchException ex) { - // Skip over non-integer input - input.nextLine(); - } - - // Process user choice - switch(choice) { - case 0: - // Exit the program - System.out.println("Goodbye..."); - break; - case 1: - // Display access token - System.out.println("Access token: " + accessToken); - break; - case 2: - // List the calendar - break; - default: - System.out.println("Invalid choice"); - } - } - - input.close(); - } -} diff --git a/demos/02-add-aad-auth/graphtutorial/src/main/resources/com/contoso/oAuth.properties.example b/demos/02-add-aad-auth/graphtutorial/src/main/resources/com/contoso/oAuth.properties.example deleted file mode 100644 index 8aff760..0000000 --- a/demos/02-add-aad-auth/graphtutorial/src/main/resources/com/contoso/oAuth.properties.example +++ /dev/null @@ -1,2 +0,0 @@ -app.id=YOUR_APP_ID_HERE -app.scopes=User.Read,Calendars.Read \ No newline at end of file diff --git a/demos/02-add-aad-auth/graphtutorial/src/test/java/com/contoso/AppTest.java b/demos/02-add-aad-auth/graphtutorial/src/test/java/com/contoso/AppTest.java deleted file mode 100644 index 6a9717e..0000000 --- a/demos/02-add-aad-auth/graphtutorial/src/test/java/com/contoso/AppTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.contoso; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -/** - * Unit test for simple App. - */ -public class AppTest -{ - /** - * Rigorous Test :-) - */ - @Test - public void shouldAnswerWithTrue() - { - assertTrue( true ); - } -} diff --git a/demos/03-add-msgraph/graphtutorial/.classpath b/demos/03-add-msgraph/graphtutorial/.classpath deleted file mode 100644 index afadaf6..0000000 --- a/demos/03-add-msgraph/graphtutorial/.classpath +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/03-add-msgraph/graphtutorial/.factorypath b/demos/03-add-msgraph/graphtutorial/.factorypath deleted file mode 100644 index 5e74494..0000000 --- a/demos/03-add-msgraph/graphtutorial/.factorypath +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/03-add-msgraph/graphtutorial/.project b/demos/03-add-msgraph/graphtutorial/.project deleted file mode 100644 index 2fae9f9..0000000 --- a/demos/03-add-msgraph/graphtutorial/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - graphtutorial - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.core.resources.prefs b/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 839d647..0000000 --- a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,5 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding/=UTF-8 diff --git a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs b/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index 687ad91..0000000 --- a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=true -org.eclipse.jdt.apt.genSrcDir=target\\generated-sources\\annotations -org.eclipse.jdt.apt.genTestSrcDir=target\\generated-test-sources\\test-annotations diff --git a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.jdt.core.prefs b/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 399797f..0000000 --- a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=12 -org.eclipse.jdt.core.compiler.compliance=12 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.processAnnotations=enabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=12 diff --git a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.m2e.core.prefs b/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/demos/03-add-msgraph/graphtutorial/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/demos/03-add-msgraph/graphtutorial/pom.xml b/demos/03-add-msgraph/graphtutorial/pom.xml deleted file mode 100644 index 4e3e00d..0000000 --- a/demos/03-add-msgraph/graphtutorial/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - 4.0.0 - - com.contoso - graphtutorial - 1.0-SNAPSHOT - - graphtutorial - - http://www.example.com - - - UTF-8 - 12 - 12 - - - - - - org.slf4j - slf4j-nop - 1.8.0-beta4 - - - - com.microsoft.graph - microsoft-graph - 1.6.0 - - - - com.microsoft.azure - msal4j - 1.1.0 - - - - junit - junit - 4.11 - test - - - - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - diff --git a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/Authentication.java b/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/Authentication.java deleted file mode 100644 index c0df4f6..0000000 --- a/demos/03-add-msgraph/graphtutorial/src/main/java/com/contoso/Authentication.java +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -package com.contoso; -import java.net.MalformedURLException; -import java.util.Set; -import java.util.function.Consumer; - -import com.microsoft.aad.msal4j.DeviceCode; -import com.microsoft.aad.msal4j.DeviceCodeFlowParameters; -import com.microsoft.aad.msal4j.IAuthenticationResult; -import com.microsoft.aad.msal4j.PublicClientApplication; - -/** - * Authentication - */ -public class Authentication { - - private static String applicationId = null; - // Set authority to allow only organizational accounts - // Device code flow only supports organizational accounts - private final static String authority = "https://login.microsoftonline.com/common/"; - - public static void initialize(String applicationId) { - Authentication.applicationId = applicationId; - } - - public static String getUserAccessToken(String[] scopes) { - if (applicationId == null) { - System.out.println("You must initialize Authentication before calling getUserAccessToken"); - return null; - } - - Set scopeSet = Set.of(scopes); - - PublicClientApplication app; - try { - // Build the MSAL application object with - // app ID and authority - app = PublicClientApplication.builder(applicationId) - .authority(authority) - .build(); - } catch (MalformedURLException e) { - return null; - } - - // Create consumer to receive the DeviceCode object - // This method gets executed during the flow and provides - // the URL the user logs into and the device code to enter - Consumer deviceCodeConsumer = (DeviceCode deviceCode) -> { - // Print the login information to the console - System.out.println(deviceCode.message()); - }; - - // Request a token, passing the requested permission scopes - IAuthenticationResult result = app.acquireToken( - DeviceCodeFlowParameters - .builder(scopeSet, deviceCodeConsumer) - .build() - ).exceptionally(ex -> { - System.out.println("Unable to authenticate - " + ex.getMessage()); - return null; - }).join(); - - if (result != null) { - return result.accessToken(); - } - - return null; - } -} \ No newline at end of file diff --git a/demos/03-add-msgraph/graphtutorial/src/main/resources/com/contoso/oAuth.properties.example b/demos/03-add-msgraph/graphtutorial/src/main/resources/com/contoso/oAuth.properties.example deleted file mode 100644 index 8aff760..0000000 --- a/demos/03-add-msgraph/graphtutorial/src/main/resources/com/contoso/oAuth.properties.example +++ /dev/null @@ -1,2 +0,0 @@ -app.id=YOUR_APP_ID_HERE -app.scopes=User.Read,Calendars.Read \ No newline at end of file diff --git a/demos/03-add-msgraph/graphtutorial/src/test/java/com/contoso/AppTest.java b/demos/03-add-msgraph/graphtutorial/src/test/java/com/contoso/AppTest.java deleted file mode 100644 index 6a9717e..0000000 --- a/demos/03-add-msgraph/graphtutorial/src/test/java/com/contoso/AppTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.contoso; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -/** - * Unit test for simple App. - */ -public class AppTest -{ - /** - * Rigorous Test :-) - */ - @Test - public void shouldAnswerWithTrue() - { - assertTrue( true ); - } -} diff --git a/tutorial/01-intro.md b/tutorial/01-intro.md index 16b9a7d..a4166e3 100644 --- a/tutorial/01-intro.md +++ b/tutorial/01-intro.md @@ -7,10 +7,15 @@ This tutorial teaches you how to build a Java console app that uses the Microsof ## Prerequisites -Before you start this tutorial, you should have the [Java SE Development Kit (JDK)](https://java.com/en/download/faq/develop.xml) and [Maven](https://maven.apache.org/) installed on your development machine. If you do not have the JDK or Maven, visit the previous links for download options. +Before you start this tutorial, you should have the [Java SE Development Kit (JDK)](https://java.com/en/download/faq/develop.xml) and [Gradle](https://gradle.org/) installed on your development machine. If you do not have the JDK or Maven, visit the previous links for download options. + +You should also have either a personal Microsoft account with a mailbox on Outlook.com, or a Microsoft work or school account. If you don't have a Microsoft account, there are a couple of options to get a free account: + +- You can [sign up for a new personal Microsoft account](https://signup.live.com/signup?wa=wsignin1.0&rpsnv=12&ct=1454618383&rver=6.4.6456.0&wp=MBI_SSL_SHARED&wreply=https://mail.live.com/default.aspx&id=64855&cbcxt=mai&bk=1454618383&uiflavor=web&uaid=b213a65b4fdc484382b6622b3ecaa547&mkt=E-US&lc=1033&lic=1). +- You can [sign up for the Office 365 Developer Program](https://developer.microsoft.com/office/dev-program) to get a free Office 365 subscription. > [!NOTE] -> This tutorial was written with OpenJDK version 12.0.1 and Maven 3.6.1. The steps in this guide may work with other versions, but that has not been tested. +> This tutorial was written with OpenJDK version 14.0.0.36 and Gradle 6.3. The steps in this guide may work with other versions, but that has not been tested. ## Feedback diff --git a/tutorial/02-create-app.md b/tutorial/02-create-app.md index 8182302..32f6b8c 100644 --- a/tutorial/02-create-app.md +++ b/tutorial/02-create-app.md @@ -1,107 +1,95 @@ -Open your command-line interface (CLI) in a directory where you want to create the project. Run the following command to create a new Maven project. +In this section you'll create a basic Java console app. -```Shell -mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.contoso -DartifactId=graphtutorial -Dversion=1.0-SNAPSHOT -``` +1. Open your command-line interface (CLI) in a directory where you want to create the project. Run the following command to create a new Gradle project. -> [!IMPORTANT] -> You can enter different values for the group ID (`DgroupId` parameter) and artifact ID (`DartifactId` parameter) than the values specified above. The sample code in this tutorial assumes that the group ID `com.contoso` was used. If you use a different value, be sure to replace `com.contoso` in any sample code with your group ID. + ```Shell + gradle init --dsl groovy --test-framework junit --type java-application --project-name graphtutorial --package graphtutorial + ``` -When prompted, confirm the configuration, then wait for the project to be created. Once the project is created, verify that it works by running the following commands to package and run the app in your CLI. +1. Once the project is created, verify that it works by running the following command to run the app in your CLI. -```Shell -mvn package -java -cp target/graphtutorial-1.0-SNAPSHOT.jar com.contoso.App -``` + ```Shell + ./gradlew --console plain run + ``` -If it works, the app should output `Hello World!`. Before moving on, add some additional dependencies that you will use later. + If it works, the app should output `Hello World.`. + +## Install dependencies + +Before moving on, add some additional dependencies that you will use later. - [Microsoft Authentication Library (MSAL) for Java](https://github.com/AzureAD/microsoft-authentication-library-for-java) to authenticate the user and acquire access tokens. - [Microsoft Graph SDK for Java](https://github.com/microsoftgraph/msgraph-sdk-java) to make calls to the Microsoft Graph. - [SLF4J NOP Binding](https://mvnrepository.com/artifact/org.slf4j/slf4j-nop) to suppress logging from MSAL. -Open **./graphtutorial/pom.xml**. Add the following inside the `` element. +1. Open **./build.gradle**. Update the `dependencies` section to add those dependencies. -```xml - - org.slf4j - slf4j-nop - 1.8.0-beta4 - + :::code language="gradle" source="../demo/graphtutorial/build.gradle" id="DependenciesSnippet" highlight="7-9"::: - - com.microsoft.graph - microsoft-graph - 1.6.0 - +1. Add the following to the end of **./build.gradle**. - - com.microsoft.azure - msal4j - 1.1.0 - -``` + :::code language="gradle" source="../demo/graphtutorial/build.gradle" id="StandardInputSnippet"::: -The next time you build the project, Maven will download those dependencies. +The next time you build the project, Gradle will download those dependencies. ## Design the app -Open the **./graphtutorial/src/main/java/com/contoso/App.java** file and replace its contents with the following. - -```java -package com.contoso; - -import java.util.InputMismatchException; -import java.util.Scanner; - -/** - * Graph Tutorial - * - */ -public class App { - public static void main(String[] args) { - System.out.println("Java Graph Tutorial"); - System.out.println(); - - Scanner input = new Scanner(System.in); - - int choice = -1; - - while (choice != 0) { - System.out.println("Please choose one of the following options:"); - System.out.println("0. Exit"); - System.out.println("1. Display access token"); - System.out.println("2. List calendar events"); - - try { - choice = input.nextInt(); - } catch (InputMismatchException ex) { - // Skip over non-integer input - input.nextLine(); +1. Open the **./src/main/java/graphtutorial/App.java** file and replace its contents with the following. + + ```java + package graphtutorial; + + import java.util.InputMismatchException; + import java.util.Scanner; + + /** + * Graph Tutorial + * + */ + public class App { + public static void main(String[] args) { + System.out.println("Java Graph Tutorial"); + System.out.println(); + + Scanner input = new Scanner(System.in); + + int choice = -1; + + while (choice != 0) { + System.out.println("Please choose one of the following options:"); + System.out.println("0. Exit"); + System.out.println("1. Display access token"); + System.out.println("2. List calendar events"); + + try { + choice = input.nextInt(); + } catch (InputMismatchException ex) { + // Skip over non-integer input + input.nextLine(); + } + + // Process user choice + switch(choice) { + case 0: + // Exit the program + System.out.println("Goodbye..."); + break; + case 1: + // Display access token + break; + case 2: + // List the calendar + break; + default: + System.out.println("Invalid choice"); + } } - // Process user choice - switch(choice) { - case 0: - // Exit the program - System.out.println("Goodbye..."); - break; - case 1: - // Display access token - break; - case 2: - // List the calendar - break; - default: - System.out.println("Invalid choice"); - } + input.close(); } - - input.close(); } -} -``` + ``` -This implements a basic menu and reads the user's choice from the command line. + This implements a basic menu and reads the user's choice from the command line. diff --git a/tutorial/03-register-app.md b/tutorial/03-register-app.md index 7bec243..3b3c087 100644 --- a/tutorial/03-register-app.md +++ b/tutorial/03-register-app.md @@ -12,7 +12,7 @@ In this exercise you will create a new Azure AD application using the Azure Acti - Set **Name** to `Java Graph Tutorial`. - Set **Supported account types** to **Accounts in any organizational directory and personal Microsoft accounts**. - - Leave **Redirect URI** empty. + - Under **Redirect URI**, change the dropdown to **Public client (mobile & desktop)**, and set the value to `https://login.microsoftonline.com/common/oauth2/nativeclient`. ![A screenshot of the Register an application page](./images/aad-register-an-app.png) @@ -20,10 +20,6 @@ In this exercise you will create a new Azure AD application using the Azure Acti ![A screenshot of the application ID of the new app registration](./images/aad-application-id.png) -1. Select the **Add a Redirect URI** link. On the **Redirect URIs** page, locate the **Suggested Redirect URIs for public clients (mobile, desktop)** section. Select the `https://login.microsoftonline.com/common/oauth2/nativeclient` URI. - - ![A screenshot of the Redirect URIs page](./images/aad-redirect-uris.png) - -1. Locate the **Default client type** section and change the **Treat application as a public client** toggle to **Yes**, then choose **Save**. +1. Select **Authentication** under **Manage**. Locate the **Advanced settings** section and change the **Treat application as a public client** toggle to **Yes**, then choose **Save**. ![A screenshot of the Default client type section](./images/aad-default-client-type.png) diff --git a/tutorial/04-add-aad-auth.md b/tutorial/04-add-aad-auth.md index 07c23e9..8bf3ba6 100644 --- a/tutorial/04-add-aad-auth.md +++ b/tutorial/04-add-aad-auth.md @@ -2,136 +2,54 @@ In this exercise you will extend the application from the previous exercise to support authentication with Azure AD. This is required to obtain the necessary OAuth access token to call the Microsoft Graph. In this step you will integrate the [Microsoft Authentication Library (MSAL) for Java](https://github.com/AzureAD/microsoft-authentication-library-for-java) into the application. -Create a new directory named **resources** in the **./graphtutorial/src/main** directory. Then create a new directory named **com** in the **resources** directory, then a new directory named **contoso** in the **com** directory. Finally, create a new file in the **./graphtutorial/src/main/resources/com/contoso** directory named **oAuth.properties**, and add the following text in that file. +1. Create a new directory named **graphtutorial** in the **./src/main/resources** directory. -```INI -app.id=YOUR_APP_ID_HERE -app.scopes=User.Read,Calendars.Read -``` +1. Create a new file in the **./src/main/resources/graphtutorial** directory named **oAuth.properties**, and add the following text in that file. -Replace `YOUR_APP_ID_HERE` with the application ID you created in the Azure portal. + :::code language="ini" source="../demo/graphtutorial/src/main/resources/graphtutorial/oAuth.properties.example"::: -> [!IMPORTANT] -> If you're using source control such as git, now would be a good time to exclude the **oAuth.properties** file from source control to avoid inadvertently leaking your app ID. + Replace `YOUR_APP_ID_HERE` with the application ID you created in the Azure portal. -Open **App.java** and add the following `import` statements. + > [!IMPORTANT] + > If you're using source control such as git, now would be a good time to exclude the **oAuth.properties** file from source control to avoid inadvertently leaking your app ID. -```java -import java.io.IOException; -import java.util.Properties; -``` +1. Open **App.java** and add the following `import` statements. -Then add the following code just before the `Scanner input = new Scanner(System.in);` line to load the **oAuth.properties** file. + ```java + import java.io.IOException; + import java.util.Properties; + ``` -```java -// Load OAuth settings -final Properties oAuthProperties = new Properties(); -try { - oAuthProperties.load(App.class.getResourceAsStream("oAuth.properties")); -} catch (IOException e) { - System.out.println("Unable to read OAuth configuration. Make sure you have a properly formatted oAuth.properties file. See README for details."); - return; -} +1. Add the following code just before the `Scanner input = new Scanner(System.in);` line to load the **oAuth.properties** file. -final String appId = oAuthProperties.getProperty("app.id"); -final String[] appScopes = oAuthProperties.getProperty("app.scopes").split(","); -``` + :::code language="java" source="../demo/graphtutorial/src/main/java/graphtutorial/App.java" id="LoadSettingsSnippet"::: ## Implement sign-in -Create a new file in the **./graphtutorial/src/main/java/com/contoso** directory named **Authentication.java** and add the following code. - -```java -package com.contoso; -import java.net.MalformedURLException; -import java.util.Set; -import java.util.function.Consumer; - -import com.microsoft.aad.msal4j.DeviceCode; -import com.microsoft.aad.msal4j.DeviceCodeFlowParameters; -import com.microsoft.aad.msal4j.IAuthenticationResult; -import com.microsoft.aad.msal4j.PublicClientApplication; - -/** - * Authentication - */ -public class Authentication { - - private static String applicationId; - // Set authority to allow only organizational accounts - // Device code flow only supports organizational accounts - private final static String authority = "https://login.microsoftonline.com/common/"; - - public static void initialize(String applicationId) { - Authentication.applicationId = applicationId; - } - - public static String getUserAccessToken(String[] scopes) { - if (applicationId == null) { - System.out.println("You must initialize Authentication before calling getUserAccessToken"); - return null; - } - - Set scopeSet = Set.of(scopes); - - PublicClientApplication app; - try { - // Build the MSAL application object with - // app ID and authority - app = PublicClientApplication.builder(applicationId) - .authority(authority) - .build(); - } catch (MalformedURLException e) { - return null; - } - - // Create consumer to receive the DeviceCode object - // This method gets executed during the flow and provides - // the URL the user logs into and the device code to enter - Consumer deviceCodeConsumer = (DeviceCode deviceCode) -> { - // Print the login information to the console - System.out.println(deviceCode.message()); - }; - - // Request a token, passing the requested permission scopes - IAuthenticationResult result = app.acquireToken( - DeviceCodeFlowParameters - .builder(scopeSet, deviceCodeConsumer) - .build() - ).exceptionally(ex -> { - System.out.println("Unable to authenticate - " + ex.getMessage()); - return null; - }).join(); - - if (result != null) { - return result.accessToken(); - } - - return null; - } -} -``` - -In **App.java**, add the following code just before the `Scanner input = new Scanner(System.in);` line to get an access token. - -```java -// Get an access token -Authentication.initialize(appId); -final String accessToken = Authentication.getUserAccessToken(appScopes); -``` - -Then add the following line after the `// Display access token` comment. - -```java -System.out.println("Access token: " + accessToken); -``` - -Build and run the app. The application displays a URL and device code. - -```Shell -Java Graph Tutorial - -To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code F7CG945YZ to authenticate. -``` - -Open a browser and browse to the URL displayed. Enter the provided code and sign in. Once completed, return to the application and choose the **1. Display access token** option to display the access token. +1. Create a new file in the **./graphtutorial/src/main/java/graphtutorial** directory named **Authentication.java** and add the following code. + + :::code language="java" source="../demo/graphtutorial/src/main/java/graphtutorial/Authentication.java" id="AuthenticationSnippet"::: + +1. In **App.java**, add the following code just before the `Scanner input = new Scanner(System.in);` line to get an access token. + + ```java + // Get an access token + Authentication.initialize(appId); + final String accessToken = Authentication.getUserAccessToken(appScopes); + ``` + +1. Add the following line after the `// Display access token` comment. + + ```java + System.out.println("Access token: " + accessToken); + ``` + +1. Run the app. The application displays a URL and device code. + + ```Shell + Java Graph Tutorial + + To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code F7CG945YZ to authenticate. + ``` + +1. Open a browser and browse to the URL displayed. Enter the provided code and sign in. Once completed, return to the application and choose the **1. Display access token** option to display the access token. diff --git a/tutorial/05-add-ms-graph.md b/tutorial/05-add-ms-graph.md index 08eca23..df919b5 100644 --- a/tutorial/05-add-ms-graph.md +++ b/tutorial/05-add-ms-graph.md @@ -4,133 +4,93 @@ In this exercise you will incorporate the Microsoft Graph into the application. ## Implement an authentication provider -The Microsoft Graph SDK for Java requires an implementation of the `IAuthenticationProvider` interface to instantiate its `GraphServiceClient` object. Start by creating a simple class to add the access token to outgoing requests. Create a new file in the **./graphtutorial/src/main/java/com/contoso** directory named **SimpleAuthProvider.java** and add the following code. +The Microsoft Graph SDK for Java requires an implementation of the `IAuthenticationProvider` interface to instantiate its `GraphServiceClient` object. -```java -package com.contoso; +1. Create a new file in the **./graphtutorial/src/main/java/graphtutorial** directory named **SimpleAuthProvider.java** and add the following code. -import com.microsoft.graph.authentication.IAuthenticationProvider; -import com.microsoft.graph.http.IHttpRequest; - -/** - * SimpleAuthProvider - */ -public class SimpleAuthProvider implements IAuthenticationProvider { - - private String accessToken = null; - - public SimpleAuthProvider(String accessToken) { - this.accessToken = accessToken; - } - - @Override - public void authenticateRequest(IHttpRequest request) { - // Add the access token in the Authorization header - request.addHeader("Authorization", "Bearer " + accessToken); - } -} -``` + :::code language="java" source="../demo/graphtutorial/src/main/java/graphtutorial/SimpleAuthProvider.java" id="AuthProviderSnippet"::: ## Get user details -First, add a new class to contain all of the Graph functionality. Create a new file in the **./graphtutorial/src/main/java/com/contoso** directory named **Graph.java** and add the following code. - -```java -package com.contoso; - -import com.microsoft.graph.logger.DefaultLogger; -import com.microsoft.graph.logger.LoggerLevel; -import com.microsoft.graph.models.extensions.IGraphServiceClient; -import com.microsoft.graph.models.extensions.User; -import com.microsoft.graph.requests.extensions.GraphServiceClient; -import java.util.LinkedList; -import java.util.List;import com.microsoft.graph.models.extensions.Event;import com.microsoft.graph.options.Option; -import com.microsoft.graph.options.QueryOption; -/** - * Graph - */ -public class Graph { - - private static IGraphServiceClient graphClient = null; - private static SimpleAuthProvider authProvider = null; - - private static void ensureGraphClient(String accessToken) { - if (graphClient == null) { - // Create the auth provider - authProvider = new SimpleAuthProvider(accessToken); - - // Create default logger to only log errors - DefaultLogger logger = new DefaultLogger(); - logger.setLoggingLevel(LoggerLevel.ERROR); - - // Build a Graph client - graphClient = GraphServiceClient.builder() - .authenticationProvider(authProvider) - .logger(logger) - .buildClient(); +1. Create a new file in the **./graphtutorial/src/main/java/graphtutorial** directory named **Graph.java** and add the following code. + + ```java + package graphtutorial; + + import java.util.LinkedList; + import java.util.List; + + import com.microsoft.graph.logger.DefaultLogger; + import com.microsoft.graph.logger.LoggerLevel; + import com.microsoft.graph.models.extensions.Event; + import com.microsoft.graph.models.extensions.IGraphServiceClient; + import com.microsoft.graph.models.extensions.User; + import com.microsoft.graph.options.Option; + import com.microsoft.graph.options.QueryOption; + import com.microsoft.graph.requests.extensions.GraphServiceClient; + import com.microsoft.graph.requests.extensions.IEventCollectionPage; + + /** + * Graph + */ + public class Graph { + + private static IGraphServiceClient graphClient = null; + private static SimpleAuthProvider authProvider = null; + + private static void ensureGraphClient(String accessToken) { + if (graphClient == null) { + // Create the auth provider + authProvider = new SimpleAuthProvider(accessToken); + + // Create default logger to only log errors + DefaultLogger logger = new DefaultLogger(); + logger.setLoggingLevel(LoggerLevel.ERROR); + + // Build a Graph client + graphClient = GraphServiceClient.builder() + .authenticationProvider(authProvider) + .logger(logger) + .buildClient(); + } } - } - public static User getUser(String accessToken) { - ensureGraphClient(accessToken); + public static User getUser(String accessToken) { + ensureGraphClient(accessToken); - // GET /me to get authenticated user - User me = graphClient - .me() - .buildRequest() - .get(); + // GET /me to get authenticated user + User me = graphClient + .me() + .buildRequest() + .get(); - return me; + return me; + } } -} -``` - -Add the following code in **App.java** just before the `Scanner input = new Scanner(System.in);` line to get the user and output the user's display name. - -```java -// Greet the user -User user = Graph.getUser(accessToken); -System.out.println("Welcome " + user.displayName); -System.out.println(); -``` + ``` -If you run the app now, after you log in the app welcomes you by name. +1. Add the following `import` statement at the top of **App.java**. -## Get calendar events from Outlook - -Add the following `import` statements to **Graph.java**. + ```java + import com.microsoft.graph.models.extensions.User; + ``` -```java -import java.util.LinkedList; -import java.util.List; -import com.microsoft.graph.models.extensions.Event; -import com.microsoft.graph.options.Option; -import com.microsoft.graph.options.QueryOption; -import com.microsoft.graph.requests.extensions.IEventCollectionPage; -``` +1. Add the following code in **App.java** just before the `Scanner input = new Scanner(System.in);` line to get the user and output the user's display name. -Add the following function to the `Graph` class in **Graph.java** to get events from the user's calendar. + ```java + // Greet the user + User user = Graph.getUser(accessToken); + System.out.println("Welcome " + user.displayName); + System.out.println(); + ``` -```java -public static List getEvents(String accessToken) { - ensureGraphClient(accessToken); +1. Run the app. After you log in the app welcomes you by name. - // Use QueryOption to specify the $orderby query parameter - final List