From 473dc94a987755178b4e693f08ba7850b32a0737 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Tue, 24 May 2022 16:25:58 -0400 Subject: [PATCH 01/55] Create gradle.yml --- .github/workflows/gradle.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/gradle.yml diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..370d9f3 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,34 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Java CI with Gradle + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Build with Gradle + uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + with: + arguments: build From 75d8b6329b3e248ae41f6b16ce99e9ff5869ebf4 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Tue, 24 May 2022 16:29:52 -0400 Subject: [PATCH 02/55] Update gradle.yml --- .github/workflows/gradle.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 370d9f3..fe80430 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -18,6 +18,9 @@ permissions: jobs: build: + defaults: + run: + working-directory: demo/graphtutorial runs-on: ubuntu-latest From 27d7c22584ad4e26eb338dd782a626585e4ecb0f Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Tue, 24 May 2022 17:14:02 -0400 Subject: [PATCH 03/55] Update gradle.yml --- .github/workflows/gradle.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index fe80430..49840d3 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -34,4 +34,5 @@ jobs: - name: Build with Gradle uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee with: + build-root-directory: demo/graphtutorial arguments: build From 9384ed98ff857b57a56ade482dd6d4d94195987e Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Tue, 24 May 2022 17:19:56 -0400 Subject: [PATCH 04/55] Update gradle.yml --- .github/workflows/gradle.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 49840d3..bd2f635 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -31,6 +31,8 @@ jobs: with: java-version: '17' distribution: 'temurin' + - name: Make gradlew executable + run: chmod +x ./gradlew - name: Build with Gradle uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee with: From e426cfda546437933e248e90ed3a452c319912f2 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Wed, 25 May 2022 11:50:58 -0400 Subject: [PATCH 05/55] Create auto-merge-dependabot.yml --- .github/workflows/auto-merge-dependabot.yml | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/auto-merge-dependabot.yml diff --git a/.github/workflows/auto-merge-dependabot.yml b/.github/workflows/auto-merge-dependabot.yml new file mode 100644 index 0000000..6022314 --- /dev/null +++ b/.github/workflows/auto-merge-dependabot.yml @@ -0,0 +1,31 @@ +name: Auto-merge dependabot updates + +on: + pull_request: + branches: [ main ] + +permissions: + pull-requests: write + contents: write + +jobs: + + dependabot-merge: + + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Enable auto-merge for Dependabot PRs + if: ${{steps.metadata.outputs.update-type != 'version-update:semver-major'}} + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 8adf4d0315e601986fc2fefd1813afc2a864dd19 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Wed, 25 May 2022 11:53:03 -0400 Subject: [PATCH 06/55] Create dependabot.yml --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..51b2754 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gradle" # See documentation for possible values + directory: "/demo/graphtutorial/" # Location of package manifests + schedule: + interval: "weekly" From 79d0ba9f1a46a5ce40b9602a4d6c84a439f22194 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 May 2022 15:53:20 +0000 Subject: [PATCH 07/55] Bump microsoft-graph from 5.22.0 to 5.25.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.22.0 to 5.25.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.22.0...v5.25.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 0a46746..302a12b 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.azure:azure-identity:1.5.0' - implementation 'com.microsoft.graph:microsoft-graph:5.22.0' + implementation 'com.microsoft.graph:microsoft-graph:5.25.0' } // From 3267351365780ee2bd2b77d1970844838b046cb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 May 2022 15:53:30 +0000 Subject: [PATCH 08/55] Bump guava from 30.1.1-jre to 31.1-jre in /demo/graphtutorial Bumps [guava](https://github.com/google/guava) from 30.1.1-jre to 31.1-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 0a46746..15f0f92 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -22,7 +22,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' // This dependency is used by the application. - implementation 'com.google.guava:guava:30.1.1-jre' + implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.0' implementation 'com.microsoft.graph:microsoft-graph:5.22.0' } From d4745290050d3735c6316eaa7be7adf783c57fdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 May 2022 15:55:04 +0000 Subject: [PATCH 09/55] Bump azure-identity from 1.5.0 to 1.5.1 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-core_1.5.0...azure-core_1.5.1) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index bd5a1e8..30e49dc 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.5.0' + implementation 'com.azure:azure-identity:1.5.1' implementation 'com.microsoft.graph:microsoft-graph:5.25.0' } // From 289f850be6b6e5ae1210a4974e8aaa194e2f6307 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Wed, 25 May 2022 12:08:09 -0400 Subject: [PATCH 10/55] Update ask-a-question.md --- .github/ISSUE_TEMPLATE/ask-a-question.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/ask-a-question.md b/.github/ISSUE_TEMPLATE/ask-a-question.md index 5fdae5a..0ec7e74 100644 --- a/.github/ISSUE_TEMPLATE/ask-a-question.md +++ b/.github/ISSUE_TEMPLATE/ask-a-question.md @@ -10,5 +10,5 @@ assignees: '' Thank you for taking an interest in Microsoft Graph development! Please feel free to ask a question here, but keep in mind the following: - This is not an official Microsoft support channel, and our ability to respond to questions here is limited. Questions about Graph, or questions about adding a new feature to the sample, will be answered on a best-effort basis. -- Questions should be asked on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph). +- Questions should be asked on [Microsoft Q&A](https://aka.ms/askgraph). - Issues with Microsoft Graph itself should be handled through [support](https://developer.microsoft.com/graph/support). From b45a22180015a0b58a738054417f5daef0161ea9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 14:36:32 +0000 Subject: [PATCH 11/55] Bump microsoft-graph from 5.25.0 to 5.26.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.25.0 to 5.26.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.25.0...v5.26.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 30e49dc..28a678e 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.1' - implementation 'com.microsoft.graph:microsoft-graph:5.25.0' + implementation 'com.microsoft.graph:microsoft-graph:5.26.0' } // From 1271fc02727dd1b1dc087404b88722d82cf2d52c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 14:38:37 +0000 Subject: [PATCH 12/55] Bump azure-identity from 1.5.1 to 1.5.2 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-core_1.5.1...azure-identity_1.5.2) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 28a678e..af42c95 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.5.1' + implementation 'com.azure:azure-identity:1.5.2' implementation 'com.microsoft.graph:microsoft-graph:5.26.0' } // From 8bb5318747512b52f9e629eec1828ef90f4195a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jun 2022 14:43:33 +0000 Subject: [PATCH 13/55] Bump microsoft-graph from 5.26.0 to 5.27.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.26.0 to 5.27.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.26.0...v5.27.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index af42c95..55ad3d2 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.2' - implementation 'com.microsoft.graph:microsoft-graph:5.26.0' + implementation 'com.microsoft.graph:microsoft-graph:5.27.0' } // From 7a5eeaac3e5cc5fa5340a82358b4829c0d3d5131 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 14:24:07 +0000 Subject: [PATCH 14/55] Bump microsoft-graph from 5.27.0 to 5.28.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.27.0 to 5.28.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.27.0...v5.28.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 55ad3d2..56528ba 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.2' - implementation 'com.microsoft.graph:microsoft-graph:5.27.0' + implementation 'com.microsoft.graph:microsoft-graph:5.28.0' } // From d24ecb8d81646e1f396af872862228e94efb60a0 Mon Sep 17 00:00:00 2001 From: "msftbot[bot]" <48340428+msftbot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:27:40 +0000 Subject: [PATCH 15/55] Add `.github/fabricbot.json` --- .github/fabricbot.json | 1149 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1149 insertions(+) create mode 100644 .github/fabricbot.json diff --git a/.github/fabricbot.json b/.github/fabricbot.json new file mode 100644 index 0000000..7f1f289 --- /dev/null +++ b/.github/fabricbot.json @@ -0,0 +1,1149 @@ +{ + "version": "1.0", + "tasks": [ + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "taskName": "Add needs triage label to new issues", + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "opened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isPartOfProject", + "parameters": {} + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isAssignedToSomeone", + "parameters": {} + } + ] + } + ] + }, + "actions": [ + { + "name": "addLabel", + "parameters": { + "label": "needs triage :mag:" + } + } + ], + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ] + }, + "id": "Muut3KbqJ" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "taskName": "Replace needs author feedback label with needs attention label when the author comments on an issue", + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "created" + } + }, + { + "name": "isActivitySender", + "parameters": { + "user": { + "type": "author" + } + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "name": "isOpen", + "parameters": {} + } + ] + }, + "actions": [ + { + "name": "addLabel", + "parameters": { + "label": "needs attention :wave:" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "needs author feedback" + } + } + ], + "eventType": "issue", + "eventNames": [ + "issue_comment" + ] + }, + "id": "8Zd_Q0LpzU" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "config": { + "taskName": "Remove no recent activity label from issues", + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + }, + { + "name": "hasLabel", + "parameters": { + "label": "no recent activity" + } + } + ] + }, + "actions": [ + { + "name": "removeLabel", + "parameters": { + "label": "no recent activity" + } + } + ], + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ] + }, + "id": "4ZLJzRdqcK" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "taskName": "Remove no recent activity label when an issue is commented on", + "conditions": { + "operator": "and", + "operands": [ + { + "name": "hasLabel", + "parameters": { + "label": "no recent activity" + } + } + ] + }, + "actions": [ + { + "name": "removeLabel", + "parameters": { + "label": "no recent activity" + } + } + ], + "eventType": "issue", + "eventNames": [ + "issue_comment" + ] + }, + "id": "q2tZhMOzht" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "config": { + "taskName": "Close stale issues", + "frequency": [ + { + "weekDay": 0, + "hours": [ + 1, + 7, + 13, + 19 + ] + }, + { + "weekDay": 1, + "hours": [ + 1, + 7, + 13, + 19 + ] + }, + { + "weekDay": 2, + "hours": [ + 1, + 7, + 13, + 19 + ] + }, + { + "weekDay": 3, + "hours": [ + 1, + 7, + 13, + 19 + ] + }, + { + "weekDay": 4, + "hours": [ + 1, + 7, + 13, + 19 + ] + }, + { + "weekDay": 5, + "hours": [ + 1, + 7, + 13, + 19 + ] + }, + { + "weekDay": 6, + "hours": [ + 1, + 7, + 13, + 19 + ] + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "no recent activity" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 3 + } + } + ], + "actions": [ + { + "name": "closeIssue", + "parameters": {} + } + ] + }, + "id": "ZF3RgW4Q0E" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "config": { + "taskName": "Add no recent activity label to issues", + "frequency": [ + { + "weekDay": 0, + "hours": [ + 2, + 8, + 14, + 20 + ] + }, + { + "weekDay": 1, + "hours": [ + 2, + 8, + 14, + 20 + ] + }, + { + "weekDay": 2, + "hours": [ + 2, + 8, + 14, + 20 + ] + }, + { + "weekDay": 3, + "hours": [ + 2, + 8, + 14, + 20 + ] + }, + { + "weekDay": 4, + "hours": [ + 2, + 8, + 14, + 20 + ] + }, + { + "weekDay": 5, + "hours": [ + 2, + 8, + 14, + 20 + ] + }, + { + "weekDay": 6, + "hours": [ + 2, + 8, + 14, + 20 + ] + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 4 + } + }, + { + "name": "noLabel", + "parameters": { + "label": "no recent activity" + } + } + ], + "actions": [ + { + "name": "addLabel", + "parameters": { + "label": "no recent activity" + } + }, + { + "name": "addReply", + "parameters": { + "comment": "This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**." + } + } + ] + }, + "id": "AiKsAHmOEk" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "config": { + "taskName": "Close duplicate issues", + "frequency": [ + { + "weekDay": 0, + "hours": [ + 3, + 9, + 15, + 21 + ] + }, + { + "weekDay": 1, + "hours": [ + 3, + 9, + 15, + 21 + ] + }, + { + "weekDay": 2, + "hours": [ + 3, + 9, + 15, + 21 + ] + }, + { + "weekDay": 3, + "hours": [ + 3, + 9, + 15, + 21 + ] + }, + { + "weekDay": 4, + "hours": [ + 3, + 9, + 15, + 21 + ] + }, + { + "weekDay": 5, + "hours": [ + 3, + 9, + 15, + 21 + ] + }, + { + "weekDay": 6, + "hours": [ + 3, + 9, + 15, + 21 + ] + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "duplicate" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 1 + } + } + ], + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "This issue has been marked as duplicate and has not had any activity for **1 day**. It will be closed for housekeeping purposes." + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ] + }, + "id": "Gmxc0WXULd" + }, + { + "taskType": "trigger", + "capabilityId": "InPrLabel", + "subCapability": "InPrLabel", + "version": "1.0", + "config": { + "taskName": "Add 'in pr' label on issue when an open pull request is targeting it", + "inPrLabelText": "Status: In PR", + "fixedLabelText": "Status: Fixed", + "fixedLabelEnabled": true, + "label_inPr": "in pr", + "label_fixed": "fixed" + }, + "id": "8BU8mPT19B" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isOpen", + "parameters": {} + } + ] + }, + { + "name": "isAction", + "parameters": { + "action": "created" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "no recent activity" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "noActivitySince", + "parameters": { + "days": 7 + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + }, + { + "name": "isActivitySender", + "parameters": { + "user": { + "type": "author" + } + } + }, + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "none" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "For issues closed due to inactivity, re-open an issue if issue author posts a reply within 7 days.", + "actions": [ + { + "name": "reopenIssue", + "parameters": {} + }, + { + "name": "removeLabel", + "parameters": { + "label": "no recent activity" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "name": "addLabel", + "parameters": { + "label": "needs attention :wave:" + } + } + ] + }, + "id": "Xvsk2Zbo4N" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueCommentResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "created" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isOpen", + "parameters": {} + } + ] + }, + { + "name": "activitySenderHasPermissions", + "parameters": { + "permissions": "none" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 7 + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isCloseAndComment", + "parameters": {} + } + ] + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issue_comment" + ], + "taskName": "For issues closed with no activity over 7 days, ask non-contributor to consider opening a new issue instead.", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Hello lovely human, thank you for your comment on this issue. Because this issue has been closed for a period of time, please strongly consider opening a new issue linking to this issue instead to ensure better visibility of your comment. Thank you!" + } + } + ] + }, + "id": "FCElTeqLrZ" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "config": { + "frequency": [ + { + "weekDay": 0, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 1, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 2, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 3, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 4, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 5, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 6, + "hours": [ + 0, + 6, + 12, + 18 + ] + } + ], + "searchTerms": [ + { + "name": "isClosed", + "parameters": {} + }, + { + "name": "noActivitySince", + "parameters": { + "days": 14 + } + }, + { + "name": "isUnlocked", + "parameters": {} + }, + { + "name": "isIssue", + "parameters": {} + } + ], + "taskName": "Lock issues closed without activity for over 14 days", + "actions": [ + { + "name": "lockIssue", + "parameters": { + "reason": "resolved" + } + } + ] + }, + "id": "n_e5TS1V5z" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "config": { + "frequency": [ + { + "weekDay": 0, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 1, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 2, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 3, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 4, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 5, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 6, + "hours": [ + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "timezoneOffset": -4 + } + ], + "searchTerms": [ + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "graph question" + } + } + ], + "taskName": "Close issues marked as Graph question", + "actions": [ + { + "name": "removeLabel", + "parameters": { + "label": "needs attention :wave:" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "needs triage :mag:" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "no recent activity" + } + }, + { + "name": "addLabel", + "parameters": { + "label": "out of scope" + } + }, + { + "name": "addReply", + "parameters": { + "comment": "It looks like you are asking a question about using Microsoft Graph or one of the Microsoft Graph SDKs that is not directly related to this sample. Unfortunately we are not set up to answer general questions in this repository, so this issue will be closed.\n\nPlease try asking your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/microsoft-graph-api), tagging your question with `microsoft-graph-api`." + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ] + }, + "id": "A6gQ1x4vaD" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "config": { + "frequency": [ + { + "weekDay": 0, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 1, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 2, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 3, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 4, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 5, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + }, + { + "weekDay": 6, + "hours": [ + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22 + ], + "timezoneOffset": -4 + } + ], + "searchTerms": [ + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "graph issue" + } + } + ], + "taskName": "Close issues marked as Graph issue", + "actions": [ + { + "name": "removeLabel", + "parameters": { + "label": "needs attention :wave:" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "needs author feedback" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "needs triage :mag:" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "no recent activity" + } + }, + { + "name": "addLabel", + "parameters": { + "label": "out of scope" + } + }, + { + "name": "addReply", + "parameters": { + "comment": "It looks like you are reporting an issue with Microsoft Graph or one of the Microsoft Graph SDKs that is not fixable by changing code in this sample. Unfortunately we are not set up to provide product support in this repository, so this issue will be closed.\n\nPlease visit one of the following links to report your issue.\n\n- Issue with Microsoft Graph service: [Microsoft Graph support](https://developer.microsoft.com/graph/support#report-issues-with-the-service), choose one of the options under **Report issues with the service**\n- Issue with a Microsoft Graph SDK: Open an issue in the SDK's GitHub repository. See [microsoftgraph on GitHub](https://github.com/microsoftgraph?q=sdk+in%3Aname&type=public&language=) for a list of SDK repositories." + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ] + }, + "id": "-8nmPYPKJs" + } + ], + "userGroups": [] +} From ed4255ca8825f7844b6f9f3903644482033d8bc6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 14:36:03 +0000 Subject: [PATCH 16/55] Bump azure-identity from 1.5.2 to 1.5.3 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.5.2 to 1.5.3. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-identity_1.5.2...azure-identity_1.5.3) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 56528ba..9c41c9e 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.5.2' + implementation 'com.azure:azure-identity:1.5.3' implementation 'com.microsoft.graph:microsoft-graph:5.28.0' } // From 230c3932c69c9b46afca6d09037b6c4a8cd02d7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 14:37:27 +0000 Subject: [PATCH 17/55] Bump microsoft-graph from 5.28.0 to 5.29.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.28.0 to 5.29.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.28.0...v5.29.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 9c41c9e..3b0d504 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.3' - implementation 'com.microsoft.graph:microsoft-graph:5.28.0' + implementation 'com.microsoft.graph:microsoft-graph:5.29.0' } // From 8e393f76f9485a28b8aa2a57141210b6a02001ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:54:31 +0000 Subject: [PATCH 18/55] Bump microsoft-graph from 5.29.0 to 5.30.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.29.0 to 5.30.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.29.0...v5.30.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 3b0d504..12a5172 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.3' - implementation 'com.microsoft.graph:microsoft-graph:5.29.0' + implementation 'com.microsoft.graph:microsoft-graph:5.30.0' } // From 14d84510e2bbb2666f48f10ef0f64aad4a9eb13e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 14:19:39 +0000 Subject: [PATCH 19/55] Bump microsoft-graph from 5.30.0 to 5.31.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.30.0 to 5.31.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.30.0...v5.31.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 12a5172..6dfa682 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.3' - implementation 'com.microsoft.graph:microsoft-graph:5.30.0' + implementation 'com.microsoft.graph:microsoft-graph:5.31.0' } // From f25bbd5c63cc31374f8b0f42b14e7dbf2323b320 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:20:52 +0000 Subject: [PATCH 20/55] Bump microsoft-graph from 5.31.0 to 5.32.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.31.0 to 5.32.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.31.0...v5.32.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 6dfa682..d58abb1 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.3' - implementation 'com.microsoft.graph:microsoft-graph:5.31.0' + implementation 'com.microsoft.graph:microsoft-graph:5.32.0' } // From cde29ec5358f7e36ec313d46484b905472c40002 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:24:23 +0000 Subject: [PATCH 21/55] Bump azure-identity from 1.5.3 to 1.5.4 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.5.3 to 1.5.4. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-identity_1.5.3...azure-identity_1.5.4) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index d58abb1..a13ed76 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.5.3' + implementation 'com.azure:azure-identity:1.5.4' implementation 'com.microsoft.graph:microsoft-graph:5.32.0' } // From bc564edd646d92042f84544358299e49c50b173d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 14:25:43 +0000 Subject: [PATCH 22/55] Bump microsoft-graph from 5.32.0 to 5.33.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.32.0 to 5.33.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.32.0...v5.33.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index a13ed76..df9162a 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.4' - implementation 'com.microsoft.graph:microsoft-graph:5.32.0' + implementation 'com.microsoft.graph:microsoft-graph:5.33.0' } // From f4df51c08309b621cf6af607dd515921cdcdfa67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:31:16 +0000 Subject: [PATCH 23/55] Bump microsoft-graph from 5.33.0 to 5.34.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.33.0 to 5.34.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.33.0...v5.34.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index df9162a..fb3c3e6 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.4' - implementation 'com.microsoft.graph:microsoft-graph:5.33.0' + implementation 'com.microsoft.graph:microsoft-graph:5.34.0' } // From faa78d4b2ee01a3a1b6aee42981797a354ab5983 Mon Sep 17 00:00:00 2001 From: "microsoft-github-policy-service[bot]" <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:32:20 +0000 Subject: [PATCH 24/55] Microsoft mandatory file --- SECURITY.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..e138ec5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + From f103629f00ad3751d9d4ac930b0511c851a5e8c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:32:54 +0000 Subject: [PATCH 25/55] Bump azure-identity from 1.5.4 to 1.5.5 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.5.4 to 1.5.5. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-identity_1.5.4...azure-identity_1.5.5) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index fb3c3e6..f0e7853 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.5.4' + implementation 'com.azure:azure-identity:1.5.5' implementation 'com.microsoft.graph:microsoft-graph:5.34.0' } // From 281310489601b0af1de96d1c7615951cb8660560 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 14:56:47 +0000 Subject: [PATCH 26/55] Bump microsoft-graph from 5.34.0 to 5.35.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.34.0 to 5.35.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/commits) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index f0e7853..617a109 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.5' - implementation 'com.microsoft.graph:microsoft-graph:5.34.0' + implementation 'com.microsoft.graph:microsoft-graph:5.35.0' } // From 325ec88fe41af71b543c6a9d86496ee628e9fe98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 14:30:14 +0000 Subject: [PATCH 27/55] Bump microsoft-graph from 5.35.0 to 5.36.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.35.0 to 5.36.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/commits/v5.36.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 617a109..f4ce72c 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.5.5' - implementation 'com.microsoft.graph:microsoft-graph:5.35.0' + implementation 'com.microsoft.graph:microsoft-graph:5.36.0' } // From b68a62f19d499ed86a74763a5cb66e3e739887a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 14:31:58 +0000 Subject: [PATCH 28/55] Bump azure-identity from 1.5.5 to 1.6.0 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.5.5 to 1.6.0. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-identity_1.5.5...azure-core_1.6.0) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index f4ce72c..6b2c414 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.5.5' + implementation 'com.azure:azure-identity:1.6.0' implementation 'com.microsoft.graph:microsoft-graph:5.36.0' } // From b50bd26252ee45e5b84f82a4c2407c4e80b9e48b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 15:29:30 +0000 Subject: [PATCH 29/55] Bump azure-identity from 1.6.0 to 1.6.1 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.6.0 to 1.6.1. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-core_1.6.0...azure-identity_1.6.1) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 6b2c414..eaaa90a 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.6.0' + implementation 'com.azure:azure-identity:1.6.1' implementation 'com.microsoft.graph:microsoft-graph:5.36.0' } // From 184c03f2f00ec6be8b93d815e5860094d71d8d0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:47:29 +0000 Subject: [PATCH 30/55] Bump microsoft-graph from 5.36.0 to 5.38.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.36.0 to 5.38.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.36.0...v5.38.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index eaaa90a..f561e27 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.6.1' - implementation 'com.microsoft.graph:microsoft-graph:5.36.0' + implementation 'com.microsoft.graph:microsoft-graph:5.38.0' } // From 661816d8c6ce377f33406bf5a543e9644f4e8186 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 14:28:31 +0000 Subject: [PATCH 31/55] Bump microsoft-graph from 5.38.0 to 5.39.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.38.0 to 5.39.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.38.0...v5.39.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index f561e27..cb63e7a 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.6.1' - implementation 'com.microsoft.graph:microsoft-graph:5.38.0' + implementation 'com.microsoft.graph:microsoft-graph:5.39.0' } // From 3a2512368772a17ce3ed2f0e178637064eec6088 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 14:04:25 +0000 Subject: [PATCH 32/55] Bump microsoft-graph from 5.39.0 to 5.40.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.39.0 to 5.40.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.39.0...v5.40.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index cb63e7a..6385602 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.6.1' - implementation 'com.microsoft.graph:microsoft-graph:5.39.0' + implementation 'com.microsoft.graph:microsoft-graph:5.40.0' } // From c5130fb438d27c1d7754902f8ee171ce8c1ee04a Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 12:08:28 -0500 Subject: [PATCH 33/55] Renamed demo directory --- {demo => user-auth}/README.md | 0 {demo => user-auth}/RegisterAppForUserAuth.ps1 | 0 {demo => user-auth}/UpdateAppForAppOnlyAuth.ps1 | 0 {demo => user-auth}/graphtutorial/.gitattributes | 0 {demo => user-auth}/graphtutorial/.gitignore | 0 {demo => user-auth}/graphtutorial/app/build.gradle | 0 .../app/src/main/java/graphtutorial/App.java | 0 .../app/src/main/java/graphtutorial/Graph.java | 0 .../graphtutorial/oAuth.properties.example | 0 .../graphtutorial/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {demo => user-auth}/graphtutorial/gradlew | 0 {demo => user-auth}/graphtutorial/gradlew.bat | 0 {demo => user-auth}/graphtutorial/settings.gradle | 0 {demo => user-auth}/version | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename {demo => user-auth}/README.md (100%) rename {demo => user-auth}/RegisterAppForUserAuth.ps1 (100%) rename {demo => user-auth}/UpdateAppForAppOnlyAuth.ps1 (100%) rename {demo => user-auth}/graphtutorial/.gitattributes (100%) rename {demo => user-auth}/graphtutorial/.gitignore (100%) rename {demo => user-auth}/graphtutorial/app/build.gradle (100%) rename {demo => user-auth}/graphtutorial/app/src/main/java/graphtutorial/App.java (100%) rename {demo => user-auth}/graphtutorial/app/src/main/java/graphtutorial/Graph.java (100%) rename {demo => user-auth}/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example (100%) rename {demo => user-auth}/graphtutorial/gradle/wrapper/gradle-wrapper.jar (100%) rename {demo => user-auth}/graphtutorial/gradle/wrapper/gradle-wrapper.properties (100%) rename {demo => user-auth}/graphtutorial/gradlew (100%) rename {demo => user-auth}/graphtutorial/gradlew.bat (100%) rename {demo => user-auth}/graphtutorial/settings.gradle (100%) rename {demo => user-auth}/version (100%) diff --git a/demo/README.md b/user-auth/README.md similarity index 100% rename from demo/README.md rename to user-auth/README.md diff --git a/demo/RegisterAppForUserAuth.ps1 b/user-auth/RegisterAppForUserAuth.ps1 similarity index 100% rename from demo/RegisterAppForUserAuth.ps1 rename to user-auth/RegisterAppForUserAuth.ps1 diff --git a/demo/UpdateAppForAppOnlyAuth.ps1 b/user-auth/UpdateAppForAppOnlyAuth.ps1 similarity index 100% rename from demo/UpdateAppForAppOnlyAuth.ps1 rename to user-auth/UpdateAppForAppOnlyAuth.ps1 diff --git a/demo/graphtutorial/.gitattributes b/user-auth/graphtutorial/.gitattributes similarity index 100% rename from demo/graphtutorial/.gitattributes rename to user-auth/graphtutorial/.gitattributes diff --git a/demo/graphtutorial/.gitignore b/user-auth/graphtutorial/.gitignore similarity index 100% rename from demo/graphtutorial/.gitignore rename to user-auth/graphtutorial/.gitignore diff --git a/demo/graphtutorial/app/build.gradle b/user-auth/graphtutorial/app/build.gradle similarity index 100% rename from demo/graphtutorial/app/build.gradle rename to user-auth/graphtutorial/app/build.gradle diff --git a/demo/graphtutorial/app/src/main/java/graphtutorial/App.java b/user-auth/graphtutorial/app/src/main/java/graphtutorial/App.java similarity index 100% rename from demo/graphtutorial/app/src/main/java/graphtutorial/App.java rename to user-auth/graphtutorial/app/src/main/java/graphtutorial/App.java diff --git a/demo/graphtutorial/app/src/main/java/graphtutorial/Graph.java b/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java similarity index 100% rename from demo/graphtutorial/app/src/main/java/graphtutorial/Graph.java rename to user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java diff --git a/demo/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example b/user-auth/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example similarity index 100% rename from demo/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example rename to user-auth/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example diff --git a/demo/graphtutorial/gradle/wrapper/gradle-wrapper.jar b/user-auth/graphtutorial/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from demo/graphtutorial/gradle/wrapper/gradle-wrapper.jar rename to user-auth/graphtutorial/gradle/wrapper/gradle-wrapper.jar diff --git a/demo/graphtutorial/gradle/wrapper/gradle-wrapper.properties b/user-auth/graphtutorial/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from demo/graphtutorial/gradle/wrapper/gradle-wrapper.properties rename to user-auth/graphtutorial/gradle/wrapper/gradle-wrapper.properties diff --git a/demo/graphtutorial/gradlew b/user-auth/graphtutorial/gradlew similarity index 100% rename from demo/graphtutorial/gradlew rename to user-auth/graphtutorial/gradlew diff --git a/demo/graphtutorial/gradlew.bat b/user-auth/graphtutorial/gradlew.bat similarity index 100% rename from demo/graphtutorial/gradlew.bat rename to user-auth/graphtutorial/gradlew.bat diff --git a/demo/graphtutorial/settings.gradle b/user-auth/graphtutorial/settings.gradle similarity index 100% rename from demo/graphtutorial/settings.gradle rename to user-auth/graphtutorial/settings.gradle diff --git a/demo/version b/user-auth/version similarity index 100% rename from demo/version rename to user-auth/version From 2bda9583d5046ed09fa2e36eebe72ab2c56b8dc3 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 12:21:12 -0500 Subject: [PATCH 34/55] Copied project for app-only --- app-auth/README.md | 125 ++++++++++ app-auth/RegisterAppForAppOnlyAuth.ps1 | 113 +++++++++ app-auth/graphapponlytutorial/.gitattributes | 6 + app-auth/graphapponlytutorial/.gitignore | 5 + .../graphapponlytutorial/app/build.gradle | 40 +++ .../main/java/graphapponlytutorial/App.java | 209 ++++++++++++++++ .../main/java/graphapponlytutorial/Graph.java | 201 +++++++++++++++ .../oAuth.properties.example | 5 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59821 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + app-auth/graphapponlytutorial/gradlew | 234 ++++++++++++++++++ app-auth/graphapponlytutorial/gradlew.bat | 89 +++++++ app-auth/graphapponlytutorial/settings.gradle | 11 + 13 files changed, 1043 insertions(+) create mode 100644 app-auth/README.md create mode 100644 app-auth/RegisterAppForAppOnlyAuth.ps1 create mode 100644 app-auth/graphapponlytutorial/.gitattributes create mode 100644 app-auth/graphapponlytutorial/.gitignore create mode 100644 app-auth/graphapponlytutorial/app/build.gradle create mode 100644 app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java create mode 100644 app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java create mode 100644 app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example create mode 100644 app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.jar create mode 100644 app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.properties create mode 100644 app-auth/graphapponlytutorial/gradlew create mode 100644 app-auth/graphapponlytutorial/gradlew.bat create mode 100644 app-auth/graphapponlytutorial/settings.gradle diff --git a/app-auth/README.md b/app-auth/README.md new file mode 100644 index 0000000..bd9d8a9 --- /dev/null +++ b/app-auth/README.md @@ -0,0 +1,125 @@ +# How to run the completed project + +## Prerequisites + +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 [Gradle](https://gradle.org/) installed on your development machine. (**Note:** This tutorial was written with OpenJDK version 17.0.2 and Gradle 7.4.2. 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 Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program) to get a free Microsoft 365 subscription. + +## Register an application + +You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/get-started). + +**NOTE:** If you downloaded this code from [https://developer.microsoft.com/graph/quick-start](https://developer.microsoft.com/graph/quick-start), an app registration has already been created for you. However, if you want to use the app-only portion of this sample, you will need to modify the app registration as specified in [Configure app-only auth (AAD admin center)](#configure-app-only-auth-aad-admin-center) or [Configure app-only auth (PowerShell)](#configure-app-only-auth-powershell). + +### Azure Active Directory admin center + +1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**. + +1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations** under **Manage**. + +1. Select **New registration**. Enter a name for your application, for example, `Java Graph Tutorial`. + +1. Set **Supported account types** as desired. The options are: + + | Option | Who can sign in? | + |--------|------------------| + | **Accounts in this organizational directory only** | Only users in your Microsoft 365 organization | + | **Accounts in any organizational directory** | Users in any Microsoft 365 organization (work or school accounts) | + | **Accounts in any organizational directory ... and personal Microsoft accounts** | Users in any Microsoft 365 organization (work or school accounts) and personal Microsoft accounts | + +1. Leave **Redirect URI** empty. + +1. Select **Register**. On the application's **Overview** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step. If you chose **Accounts in this organizational directory only** for **Supported account types**, also copy the **Directory (tenant) ID** and save it. + +1. Select **Authentication** under **Manage**. Locate the **Advanced settings** section and change the **Allow public client flows** toggle to **Yes**, then choose **Save**. + +#### Configure app-only auth (AAD admin center) + +> **Note:** This section requires a work/school account with the Global administrator role. You only need to complete these steps if you plan on using the app-only portions of this sample. + +1. Select **API permissions** under **Manage**. + +1. Remove the default **User.Read** permission under **Configured permissions** by selecting the ellipses (**...**) in its row and selecting **Remove permission**. + +1. Select **Add a permission**, then **Microsoft Graph**. + +1. Select **Application permissions**. + +1. Select **User.Read.All**, then select **Add permissions**. + +1. Select **Grant admin consent for...**, then select **Yes** to provide admin consent for the selected permission. + +1. Select **Certificates and secrets** under **Manage**, then select **New client secret**. + +1. Enter a description, choose a duration, and select **Add**. + +1. Copy the secret from the **Value** column, you will need it in the next steps. + +### PowerShell + +To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/installation) for installation instructions. + +1. Open PowerShell and run the [RegisterAppForUserAuth.ps1](RegisterAppForUserAuth.ps1) file with the following command, replacing *<audience-value>* with the desired value (see table below). + + > **Note:** The RegisterAppForUserAuth.ps1 script requires a work/school account with the Application administrator, Cloud application administrator, or Global administrator role. + + ```powershell + .\RegisterAppForUserAuth.ps1 -AppName "Java Graph Tutorial" -SignInAudience + ``` + + | SignInAudience value | Who can sign in? | + |----------------------|------------------| + | `AzureADMyOrg` | Only users in your Microsoft 365 organization | + | `AzureADMultipleOrgs` | Users in any Microsoft 365 organization (work or school accounts) | + | `AzureADandPersonalMicrosoftAccount` | Users in any Microsoft 365 organization (work or school accounts) and personal Microsoft accounts | + | `PersonalMicrosoftAccount` | Only personal Microsoft accounts | + +1. Copy the **Client ID** and **Auth tenant** values from the script output. You will need these values in the next step. + + ```powershell + SUCCESS + Client ID: 2fb1652f-a9a0-4db9-b220-b224b8d9d38b + Auth tenant: common + ``` + +#### Configure app-only auth (PowerShell) + +> **Note:** This section requires a work/school account with the Global administrator role. You only need to complete these steps if you plan on using the app-only portions of this sample. + +1. Run the [UpdateAppForAppOnlyAuth.ps1](UpdateAppForAppOnlyAuth.ps1) file with the following command, replacing *<your-client-id>* with your client ID. + + ```powershell + .\UpdateAppForAppOnlyAuth.ps1 -AppId -GraphScopes "User.Read.All" + ``` + +1. Copy the **Tenant ID** and **Client secret** values from the script output. You will need these values in the next step. + + ```powershell + SUCCESS + Tenant ID: a795ad0f-7d82-4a3b-a2c0-0713ec72ade7 + Client secret: 2jv7Q~8eiOd_QafJ..... + Secret expires: 2/16/2024 9:32:09 PM + ``` + +## Configure the sample + +1. Rename [oAuth.properties.example](./graphtutorial/app/src/main/resources/oAuth.properties.example) to `oauthProperties` and update the values according to the following table. + + | Setting | Value | + |---------|-------| + | `app.clientId` | The client ID of your app registration | + | `app.clientSecret` | The client secret (only needed if doing app-only) | + | `app.tenantId` | The tenant ID of your organization (only needed if doing app-only) | + | `app.authTenant` | If you chose the option to only allow users in your organization to sign in, change this value to your tenant ID. Otherwise leave as `common`. | + +## Build and run the sample + +In your command-line interface (CLI), navigate to the project directory and run the following command. + +```Shell +./gradlew --console plain run +``` diff --git a/app-auth/RegisterAppForAppOnlyAuth.ps1 b/app-auth/RegisterAppForAppOnlyAuth.ps1 new file mode 100644 index 0000000..09ce5e0 --- /dev/null +++ b/app-auth/RegisterAppForAppOnlyAuth.ps1 @@ -0,0 +1,113 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. + +# +param( + [Parameter(Mandatory=$true, + HelpMessage="The friendly name of the app registration")] + [String] + $AppName, + + [Parameter(Mandatory=$true, + HelpMessage="The application permission scopes to configure on the app registration")] + [String[]] + $GraphScopes, + + [Parameter(Mandatory=$false)] + [Switch] + $StayConnected = $false +) + +$graphAppId = "00000003-0000-0000-c000-000000000000" + +# Requires an admin +Connect-MgGraph -Scopes "Application.ReadWrite.All User.Read" -UseDeviceAuthentication -ErrorAction Stop + +# Get context for access to tenant ID +$context = Get-MgContext -ErrorAction Stop +$authTenant = $context.TenantId + +# Create app registration +$appRegistration = New-MgApplication -DisplayName $AppName -SignInAudience "AzureADMyOrg" -ErrorAction Stop +Write-Host -ForegroundColor Cyan "App registration created with app ID" $appRegistration.AppId + +# Create corresponding service principal +$appServicePrincipal = New-MgServicePrincipal -AppId $appRegistration.AppId -ErrorAction SilentlyContinue ` + -ErrorVariable SPError +if ($SPError) +{ + Write-Host -ForegroundColor Red "A service principal for the app could not be created." + Write-Host -ForegroundColor Red $SPError + Exit +} + +Write-Host -ForegroundColor Cyan "Service principal created" + +# Lookup available Graph application permissions +$graphServicePrincipal = Get-MgServicePrincipal -Filter ("appId eq '" + $graphAppId + "'") -ErrorAction Stop +$graphAppPermissions = $graphServicePrincipal.AppRoles + +$resourceAccess = @() + +foreach($scope in $GraphScopes) +{ + $permission = $graphAppPermissions | Where-Object { $_.Value -eq $scope } + if ($permission) + { + $resourceAccess += @{ Id = $permission.Id; Type = "Role"} + } + else + { + Write-Host -ForegroundColor Red "Invalid scope:" $scope + Exit + } +} + +# Add the permissions to required resource access +Update-MgApplication -ApplicationId $appRegistration.Id -RequiredResourceAccess ` + @{ ResourceAppId = $graphAppId; ResourceAccess = $resourceAccess } -ErrorAction Stop +Write-Host -ForegroundColor Cyan "Added application permissions to app registration" + +# Add admin consent +foreach ($appRole in $resourceAccess) +{ + $appServicePrincipal + New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appServicePrincipal.Id ` + -PrincipalId $appServicePrincipal.Id -ResourceId $graphServicePrincipal.Id ` + -AppRoleId $appRole.Id -ErrorAction SilentlyContinue -ErrorVariable SPError | Out-Null + if ($SPError) + { + Write-Host -ForegroundColor Red "Admin consent for one of the requested scopes could not be added." + Write-Host -ForegroundColor Red $SPError + Exit + } +} +Write-Host -ForegroundColor Cyan "Added admin consent" + +# Add a client secret +$clientSecret = Add-MgApplicationPassword -ApplicationId $appRegistration.Id -PasswordCredential ` + @{ DisplayName = "Added by PowerShell" } -ErrorAction Stop + +Write-Host +Write-Host -ForegroundColor Green "SUCCESS" +Write-Host -ForegroundColor Cyan -NoNewline "Client ID: " +Write-Host -ForegroundColor Yellow $appRegistration.AppId +Write-Host -ForegroundColor Cyan -NoNewline "Tenant ID: " +Write-Host -ForegroundColor Yellow $authTenant +Write-Host -ForegroundColor Cyan -NoNewline "Client secret: " +Write-Host -ForegroundColor Yellow $clientSecret.SecretText +Write-Host -ForegroundColor Cyan -NoNewline "Secret expires: " +Write-Host -ForegroundColor Yellow $clientSecret.EndDateTime + +if ($StayConnected -eq $false) +{ + Disconnect-MgGraph + Write-Host "Disconnected from Microsoft Graph" +} +else +{ + Write-Host + Write-Host -ForegroundColor Yellow ` + "The connection to Microsoft Graph is still active. To disconnect, use Disconnect-MgGraph" +} +# diff --git a/app-auth/graphapponlytutorial/.gitattributes b/app-auth/graphapponlytutorial/.gitattributes new file mode 100644 index 0000000..00a51af --- /dev/null +++ b/app-auth/graphapponlytutorial/.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/app-auth/graphapponlytutorial/.gitignore b/app-auth/graphapponlytutorial/.gitignore new file mode 100644 index 0000000..1b6985c --- /dev/null +++ b/app-auth/graphapponlytutorial/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/app-auth/graphapponlytutorial/app/build.gradle b/app-auth/graphapponlytutorial/app/build.gradle new file mode 100644 index 0000000..6b8adf3 --- /dev/null +++ b/app-auth/graphapponlytutorial/app/build.gradle @@ -0,0 +1,40 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java application project to get you started. + * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle + * User Manual available at https://docs.gradle.org/7.4.2/userguide/building_java_projects.html + */ + +plugins { + // Apply the application plugin to add support for building a CLI application in Java. + id 'application' +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +// +dependencies { + // Use JUnit test framework. + testImplementation 'junit:junit:4.13.2' + + // This dependency is used by the application. + implementation 'com.google.guava:guava:31.1-jre' + implementation 'com.azure:azure-identity:1.6.1' + implementation 'com.microsoft.graph:microsoft-graph:5.40.0' +} +// + +application { + // Define the main class for the application. + mainClass = 'graphapponlytutorial.App' +} + +// +run { + standardInput = System.in +} +// diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java new file mode 100644 index 0000000..a403457 --- /dev/null +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java @@ -0,0 +1,209 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +// +package graphapponlytutorial; + +import java.io.IOException; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.util.InputMismatchException; +import java.util.Properties; +import java.util.Scanner; + +import com.microsoft.graph.models.Message; +import com.microsoft.graph.models.User; +import com.microsoft.graph.requests.MessageCollectionPage; +import com.microsoft.graph.requests.UserCollectionPage; +// + +public class App { + // + public static void main(String[] args) { + System.out.println("Java Graph Tutorial"); + System.out.println(); + + 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; + } + + initializeGraph(oAuthProperties); + + greetUser(); + + 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 my inbox"); + System.out.println("3. Send mail"); + System.out.println("4. List users (required app-only)"); + System.out.println("5. Make a Graph call"); + + 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 + displayAccessToken(); + break; + case 2: + // List emails from user's inbox + listInbox(); + break; + case 3: + // Send an email message + sendMail(); + break; + case 4: + // List users + listUsers(); + break; + case 5: + // Run any Graph code + makeGraphCall(); + break; + default: + System.out.println("Invalid choice"); + } + } + + input.close(); + } + // + + // + private static void initializeGraph(Properties properties) { + try { + Graph.initializeGraphForUserAuth(properties, + challenge -> System.out.println(challenge.getMessage())); + } catch (Exception e) + { + System.out.println("Error initializing Graph for user auth"); + System.out.println(e.getMessage()); + } + } + // + + // + private static void greetUser() { + try { + final User user = Graph.getUser(); + // For Work/school accounts, email is in mail property + // Personal accounts, email is in userPrincipalName + final String email = user.mail == null ? user.userPrincipalName : user.mail; + System.out.println("Hello, " + user.displayName + "!"); + System.out.println("Email: " + email); + } catch (Exception e) { + System.out.println("Error getting user"); + System.out.println(e.getMessage()); + } + } + // + + // + private static void displayAccessToken() { + try { + final String accessToken = Graph.getUserToken(); + System.out.println("Access token: " + accessToken); + } catch (Exception e) { + System.out.println("Error getting access token"); + System.out.println(e.getMessage()); + } + } + // + + // + private static void listInbox() { + try { + final MessageCollectionPage messages = Graph.getInbox(); + + // Output each message's details + for (Message message: messages.getCurrentPage()) { + System.out.println("Message: " + message.subject); + System.out.println(" From: " + message.from.emailAddress.name); + System.out.println(" Status: " + (message.isRead ? "Read" : "Unread")); + System.out.println(" Received: " + message.receivedDateTime + // Values are returned in UTC, convert to local time zone + .atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime() + .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT))); + } + + final Boolean moreMessagesAvailable = messages.getNextPage() != null; + System.out.println("\nMore messages available? " + moreMessagesAvailable); + } catch (Exception e) { + System.out.println("Error getting inbox"); + System.out.println(e.getMessage()); + } + } + // + + // + private static void sendMail() { + try { + // Send mail to the signed-in user + // Get the user for their email address + final User user = Graph.getUser(); + final String email = user.mail == null ? user.userPrincipalName : user.mail; + + Graph.sendMail("Testing Microsoft Graph", "Hello world!", email); + System.out.println("\nMail sent."); + } catch (Exception e) { + System.out.println("Error sending mail"); + System.out.println(e.getMessage()); + } + } + // + + // + private static void listUsers() { + try { + final UserCollectionPage users = Graph.getUsers(); + + // Output each user's details + for (User user: users.getCurrentPage()) { + System.out.println("User: " + user.displayName); + System.out.println(" ID: " + user.id); + System.out.println(" Email: " + user.mail); + } + + final Boolean moreUsersAvailable = users.getNextPage() != null; + System.out.println("\nMore users available? " + moreUsersAvailable); + } catch (Exception e) { + System.out.println("Error getting users"); + System.out.println(e.getMessage()); + } + } + // + + // + private static void makeGraphCall() { + try { + Graph.makeGraphCall(); + } catch (Exception e) { + System.out.println("Error making Graph call"); + System.out.println(e.getMessage()); + } + } + // +} diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java new file mode 100644 index 0000000..8faeea9 --- /dev/null +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java @@ -0,0 +1,201 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +// +package graphapponlytutorial; + +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.function.Consumer; + +import com.azure.core.credential.AccessToken; +import com.azure.core.credential.TokenRequestContext; +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.ClientSecretCredentialBuilder; +import com.azure.identity.DeviceCodeCredential; +import com.azure.identity.DeviceCodeCredentialBuilder; +import com.azure.identity.DeviceCodeInfo; +import com.microsoft.graph.authentication.TokenCredentialAuthProvider; +import com.microsoft.graph.models.BodyType; +import com.microsoft.graph.models.EmailAddress; +import com.microsoft.graph.models.ItemBody; +import com.microsoft.graph.models.Message; +import com.microsoft.graph.models.Recipient; +import com.microsoft.graph.models.User; +import com.microsoft.graph.models.UserSendMailParameterSet; +import com.microsoft.graph.requests.GraphServiceClient; +import com.microsoft.graph.requests.MessageCollectionPage; +import com.microsoft.graph.requests.UserCollectionPage; + +import okhttp3.Request; +// + +public class Graph { + // + private static Properties _properties; + private static DeviceCodeCredential _deviceCodeCredential; + private static GraphServiceClient _userClient; + + public static void initializeGraphForUserAuth(Properties properties, Consumer challenge) throws Exception { + // Ensure properties isn't null + if (properties == null) { + throw new Exception("Properties cannot be null"); + } + + _properties = properties; + + final String clientId = properties.getProperty("app.clientId"); + final String authTenantId = properties.getProperty("app.authTenant"); + final List graphUserScopes = Arrays + .asList(properties.getProperty("app.graphUserScopes").split(",")); + + _deviceCodeCredential = new DeviceCodeCredentialBuilder() + .clientId(clientId) + .tenantId(authTenantId) + .challengeConsumer(challenge) + .build(); + + final TokenCredentialAuthProvider authProvider = + new TokenCredentialAuthProvider(graphUserScopes, _deviceCodeCredential); + + _userClient = GraphServiceClient.builder() + .authenticationProvider(authProvider) + .buildClient(); + } + // + + // + public static String getUserToken() throws Exception { + // Ensure credential isn't null + if (_deviceCodeCredential == null) { + throw new Exception("Graph has not been initialized for user auth"); + } + + final String[] graphUserScopes = _properties.getProperty("app.graphUserScopes").split(","); + + final TokenRequestContext context = new TokenRequestContext(); + context.addScopes(graphUserScopes); + + final AccessToken token = _deviceCodeCredential.getToken(context).block(); + return token.getToken(); + } + // + + // + public static User getUser() throws Exception { + // Ensure client isn't null + if (_userClient == null) { + throw new Exception("Graph has not been initialized for user auth"); + } + + return _userClient.me() + .buildRequest() + .select("displayName,mail,userPrincipalName") + .get(); + } + // + + // + public static MessageCollectionPage getInbox() throws Exception { + // Ensure client isn't null + if (_userClient == null) { + throw new Exception("Graph has not been initialized for user auth"); + } + + return _userClient.me() + .mailFolders("inbox") + .messages() + .buildRequest() + .select("from,isRead,receivedDateTime,subject") + .top(25) + .orderBy("receivedDateTime DESC") + .get(); + } + // + + // + public static void sendMail(String subject, String body, String recipient) throws Exception { + // Ensure client isn't null + if (_userClient == null) { + throw new Exception("Graph has not been initialized for user auth"); + } + + // Create a new message + final Message message = new Message(); + message.subject = subject; + message.body = new ItemBody(); + message.body.content = body; + message.body.contentType = BodyType.TEXT; + + final Recipient toRecipient = new Recipient(); + toRecipient.emailAddress = new EmailAddress(); + toRecipient.emailAddress.address = recipient; + message.toRecipients = List.of(toRecipient); + + // Send the message + _userClient.me() + .sendMail(UserSendMailParameterSet.newBuilder() + .withMessage(message) + .build()) + .buildRequest() + .post(); + } + // + + // + private static ClientSecretCredential _clientSecretCredential; + private static GraphServiceClient _appClient; + + private static void ensureGraphForAppOnlyAuth() throws Exception { + // Ensure _properties isn't null + if (_properties == null) { + throw new Exception("Properties cannot be null"); + } + + if (_clientSecretCredential == null) { + final String clientId = _properties.getProperty("app.clientId"); + final String tenantId = _properties.getProperty("app.tenantId"); + final String clientSecret = _properties.getProperty("app.clientSecret"); + + _clientSecretCredential = new ClientSecretCredentialBuilder() + .clientId(clientId) + .tenantId(tenantId) + .clientSecret(clientSecret) + .build(); + } + + if (_appClient == null) { + final TokenCredentialAuthProvider authProvider = + new TokenCredentialAuthProvider( + List.of("https://graph.microsoft.com/.default"), _clientSecretCredential); + + _appClient = GraphServiceClient.builder() + .authenticationProvider(authProvider) + .buildClient(); + } + } + // + + // + public static UserCollectionPage getUsers() throws Exception { + ensureGraphForAppOnlyAuth(); + + return _appClient.users() + .buildRequest() + .select("displayName,id,mail") + .top(25) + .orderBy("displayName") + .get(); + } + // + + // + public static void makeGraphCall() { + // INSERT YOUR CODE HERE + // Note: if using _appClient, be sure to call ensureGraphForAppOnlyAuth + // before using it. + // ensureGraphForAppOnlyAuth(); + } + // +} diff --git a/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example b/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example new file mode 100644 index 0000000..4b54e97 --- /dev/null +++ b/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example @@ -0,0 +1,5 @@ +app.clientId=YOUR_CLIENT_ID_HERE +app.clientSecret=YOUR_CLIENT_SECRET_HERE_IF_USING_APP_ONLY +app.tenantId=YOUR_TENANT_ID_HERE_IF_USING_APP_ONLY +app.authTenant=common +app.graphUserScopes=user.read,mail.read,mail.send diff --git a/app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.jar b/app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..41d9927a4d4fb3f96a785543079b8df6723c946b GIT binary patch literal 59821 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 literal 0 HcmV?d00001 diff --git a/app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.properties b/app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..aa991fc --- /dev/null +++ b/app-auth/graphapponlytutorial/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/app-auth/graphapponlytutorial/gradlew b/app-auth/graphapponlytutorial/gradlew new file mode 100644 index 0000000..1b6c787 --- /dev/null +++ b/app-auth/graphapponlytutorial/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${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 "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# 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 ;; #( + MSYS* | 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" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/app-auth/graphapponlytutorial/gradlew.bat b/app-auth/graphapponlytutorial/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/app-auth/graphapponlytutorial/gradlew.bat @@ -0,0 +1,89 @@ +@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 execute + +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 execute + +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 + +: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 %* + +: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/app-auth/graphapponlytutorial/settings.gradle b/app-auth/graphapponlytutorial/settings.gradle new file mode 100644 index 0000000..e035f8a --- /dev/null +++ b/app-auth/graphapponlytutorial/settings.gradle @@ -0,0 +1,11 @@ +/* + * 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/7.4.2/userguide/multi_project_builds.html + */ + +rootProject.name = 'graphapponlytutorial' +include('app') From 80e6cfddb1e6d1156dd84f943465047043331fcd Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:08:34 -0500 Subject: [PATCH 35/55] Update user auth sample --- user-auth/UpdateAppForAppOnlyAuth.ps1 | 98 ------------------- .../app/src/main/java/graphtutorial/App.java | 29 +----- .../src/main/java/graphtutorial/Graph.java | 54 +--------- .../graphtutorial/oAuth.properties.example | 4 +- user-auth/version | 2 +- 5 files changed, 5 insertions(+), 182 deletions(-) delete mode 100644 user-auth/UpdateAppForAppOnlyAuth.ps1 diff --git a/user-auth/UpdateAppForAppOnlyAuth.ps1 b/user-auth/UpdateAppForAppOnlyAuth.ps1 deleted file mode 100644 index d6833c6..0000000 --- a/user-auth/UpdateAppForAppOnlyAuth.ps1 +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. - -# -param( - [Parameter(Mandatory=$true, - HelpMessage="The app ID of the app registration")] - [String] - $AppId, - - [Parameter(Mandatory=$true, - HelpMessage="The application permission scopes to configure on the app registration")] - [String[]] - $GraphScopes, - - [Parameter(Mandatory=$false)] - [Switch] - $StayConnected = $false -) - -$graphAppId = "00000003-0000-0000-c000-000000000000" - -# Requires an admin -Connect-MgGraph -Scopes "Application.ReadWrite.All AppRoleAssignment.ReadWrite.All User.Read" ` - -UseDeviceAuthentication -ErrorAction Stop - -# Get context for access to tenant ID -$context = Get-MgContext -ErrorAction Stop - -# Get the application and service principal -$appRegistration = Get-MgApplication -Filter ("appId eq '" + $AppId +"'") -ErrorAction Stop -$appServicePrincipal = Get-MgServicePrincipal -Filter ("appId eq '" + $AppId + "'") -ErrorAction Stop - -# Lookup available Graph application permissions -$graphServicePrincipal = Get-MgServicePrincipal -Filter ("appId eq '" + $graphAppId + "'") -ErrorAction Stop -$graphAppPermissions = $graphServicePrincipal.AppRoles - -$resourceAccess = @() - -foreach($scope in $GraphScopes) -{ - $permission = $graphAppPermissions | Where-Object { $_.Value -eq $scope } - if ($permission) - { - $resourceAccess += @{ Id = $permission.Id; Type = "Role"} - } - else - { - Write-Host -ForegroundColor Red "Invalid scope:" $scope - Exit - } -} - -# Add the permissions to required resource access -Update-MgApplication -ApplicationId $appRegistration.Id -RequiredResourceAccess ` - @{ ResourceAppId = $graphAppId; ResourceAccess = $resourceAccess } -ErrorAction Stop -Write-Host -ForegroundColor Cyan "Added application permissions to app registration" - -# Add admin consent -foreach ($appRole in $resourceAccess) -{ - New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appServicePrincipal.Id ` - -PrincipalId $appServicePrincipal.Id -ResourceId $graphServicePrincipal.Id ` - -AppRoleId $appRole.Id -ErrorAction SilentlyContinue -ErrorVariable SPError | Out-Null - if ($SPError) - { - Write-Host -ForegroundColor Red "Admin consent for one of the requested scopes could not be added." - Write-Host -ForegroundColor Red $SPError - Exit - } -} -Write-Host -ForegroundColor Cyan "Added admin consent" - -# Add a client secret -$clientSecret = Add-MgApplicationPassword -ApplicationId $appRegistration.Id -PasswordCredential ` - @{ DisplayName = "Added by PowerShell" } -ErrorAction Stop - -Write-Host -Write-Host -ForegroundColor Green "SUCCESS" -Write-Host -ForegroundColor Cyan -NoNewline "Tenant ID: " -Write-Host -ForegroundColor Yellow $context.TenantId -Write-Host -ForegroundColor Cyan -NoNewline "Client secret: " -Write-Host -ForegroundColor Yellow $clientSecret.SecretText -Write-Host -ForegroundColor Cyan -NoNewline "Secret expires: " -Write-Host -ForegroundColor Yellow $clientSecret.EndDateTime - -if ($StayConnected -eq $false) -{ - Disconnect-MgGraph - Write-Host "Disconnected from Microsoft Graph" -} -else -{ - Write-Host - Write-Host -ForegroundColor Yellow ` - "The connection to Microsoft Graph is still active. To disconnect, use Disconnect-MgGraph" -} -# diff --git a/user-auth/graphtutorial/app/src/main/java/graphtutorial/App.java b/user-auth/graphtutorial/app/src/main/java/graphtutorial/App.java index f5cc1a7..c70ff84 100644 --- a/user-auth/graphtutorial/app/src/main/java/graphtutorial/App.java +++ b/user-auth/graphtutorial/app/src/main/java/graphtutorial/App.java @@ -15,7 +15,6 @@ import com.microsoft.graph.models.Message; import com.microsoft.graph.models.User; import com.microsoft.graph.requests.MessageCollectionPage; -import com.microsoft.graph.requests.UserCollectionPage; // public class App { @@ -46,8 +45,7 @@ public static void main(String[] args) { System.out.println("1. Display access token"); System.out.println("2. List my inbox"); System.out.println("3. Send mail"); - System.out.println("4. List users (required app-only)"); - System.out.println("5. Make a Graph call"); + System.out.println("4. Make a Graph call"); try { choice = input.nextInt(); @@ -76,10 +74,6 @@ public static void main(String[] args) { sendMail(); break; case 4: - // List users - listUsers(); - break; - case 5: // Run any Graph code makeGraphCall(); break; @@ -175,27 +169,6 @@ private static void sendMail() { } // - // - private static void listUsers() { - try { - final UserCollectionPage users = Graph.getUsers(); - - // Output each user's details - for (User user: users.getCurrentPage()) { - System.out.println("User: " + user.displayName); - System.out.println(" ID: " + user.id); - System.out.println(" Email: " + user.mail); - } - - final Boolean moreUsersAvailable = users.getNextPage() != null; - System.out.println("\nMore users available? " + moreUsersAvailable); - } catch (Exception e) { - System.out.println("Error getting users"); - System.out.println(e.getMessage()); - } - } - // - // private static void makeGraphCall() { try { diff --git a/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java b/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java index 59e0907..464eb9f 100644 --- a/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java +++ b/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java @@ -11,8 +11,6 @@ import com.azure.core.credential.AccessToken; import com.azure.core.credential.TokenRequestContext; -import com.azure.identity.ClientSecretCredential; -import com.azure.identity.ClientSecretCredentialBuilder; import com.azure.identity.DeviceCodeCredential; import com.azure.identity.DeviceCodeCredentialBuilder; import com.azure.identity.DeviceCodeInfo; @@ -26,7 +24,6 @@ import com.microsoft.graph.models.UserSendMailParameterSet; import com.microsoft.graph.requests.GraphServiceClient; import com.microsoft.graph.requests.MessageCollectionPage; -import com.microsoft.graph.requests.UserCollectionPage; import okhttp3.Request; // @@ -46,13 +43,13 @@ public static void initializeGraphForUserAuth(Properties properties, Consumer graphUserScopes = Arrays .asList(properties.getProperty("app.graphUserScopes").split(",")); _deviceCodeCredential = new DeviceCodeCredentialBuilder() .clientId(clientId) - .tenantId(authTenantId) + .tenantId(tenantId) .challengeConsumer(challenge) .build(); @@ -143,53 +140,6 @@ public static void sendMail(String subject, String body, String recipient) throw } // - // - private static ClientSecretCredential _clientSecretCredential; - private static GraphServiceClient _appClient; - - private static void ensureGraphForAppOnlyAuth() throws Exception { - // Ensure _properties isn't null - if (_properties == null) { - throw new Exception("Properties cannot be null"); - } - - if (_clientSecretCredential == null) { - final String clientId = _properties.getProperty("app.clientId"); - final String tenantId = _properties.getProperty("app.tenantId"); - final String clientSecret = _properties.getProperty("app.clientSecret"); - - _clientSecretCredential = new ClientSecretCredentialBuilder() - .clientId(clientId) - .tenantId(tenantId) - .clientSecret(clientSecret) - .build(); - } - - if (_appClient == null) { - final TokenCredentialAuthProvider authProvider = - new TokenCredentialAuthProvider( - List.of("https://graph.microsoft.com/.default"), _clientSecretCredential); - - _appClient = GraphServiceClient.builder() - .authenticationProvider(authProvider) - .buildClient(); - } - } - // - - // - public static UserCollectionPage getUsers() throws Exception { - ensureGraphForAppOnlyAuth(); - - return _appClient.users() - .buildRequest() - .select("displayName,id,mail") - .top(25) - .orderBy("displayName") - .get(); - } - // - // public static void makeGraphCall() { // INSERT YOUR CODE HERE diff --git a/user-auth/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example b/user-auth/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example index 4b54e97..0b6ceb4 100644 --- a/user-auth/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example +++ b/user-auth/graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example @@ -1,5 +1,3 @@ app.clientId=YOUR_CLIENT_ID_HERE -app.clientSecret=YOUR_CLIENT_SECRET_HERE_IF_USING_APP_ONLY -app.tenantId=YOUR_TENANT_ID_HERE_IF_USING_APP_ONLY -app.authTenant=common +app.tenantId=common app.graphUserScopes=user.read,mail.read,mail.send diff --git a/user-auth/version b/user-auth/version index d3827e7..9459d4b 100644 --- a/user-auth/version +++ b/user-auth/version @@ -1 +1 @@ -1.0 +1.1 From 7417ff0434b05ec0bae81859dd14d51467a4444b Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:21:55 -0500 Subject: [PATCH 36/55] Update app-only sample --- .../main/java/graphapponlytutorial/App.java | 87 +--------- .../main/java/graphapponlytutorial/Graph.java | 152 +++--------------- .../oAuth.properties.example | 6 +- 3 files changed, 33 insertions(+), 212 deletions(-) diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java index a403457..b57ed56 100644 --- a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java @@ -5,23 +5,18 @@ package graphapponlytutorial; import java.io.IOException; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.time.format.FormatStyle; import java.util.InputMismatchException; import java.util.Properties; import java.util.Scanner; -import com.microsoft.graph.models.Message; import com.microsoft.graph.models.User; -import com.microsoft.graph.requests.MessageCollectionPage; import com.microsoft.graph.requests.UserCollectionPage; // public class App { // public static void main(String[] args) { - System.out.println("Java Graph Tutorial"); + System.out.println("Java App-Only Graph Tutorial"); System.out.println(); final Properties oAuthProperties = new Properties(); @@ -34,8 +29,6 @@ public static void main(String[] args) { initializeGraph(oAuthProperties); - greetUser(); - Scanner input = new Scanner(System.in); int choice = -1; @@ -44,10 +37,8 @@ public static void main(String[] args) { 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 my inbox"); - System.out.println("3. Send mail"); - System.out.println("4. List users (required app-only)"); - System.out.println("5. Make a Graph call"); + System.out.println("2. List users"); + System.out.println("3. Make a Graph call"); try { choice = input.nextInt(); @@ -68,18 +59,10 @@ public static void main(String[] args) { displayAccessToken(); break; case 2: - // List emails from user's inbox - listInbox(); - break; - case 3: - // Send an email message - sendMail(); - break; - case 4: // List users listUsers(); break; - case 5: + case 3: // Run any Graph code makeGraphCall(); break; @@ -95,7 +78,7 @@ public static void main(String[] args) { // private static void initializeGraph(Properties properties) { try { - Graph.initializeGraphForUserAuth(properties, + Graph.initializeGraphForAppOnlyAuth(properties, challenge -> System.out.println(challenge.getMessage())); } catch (Exception e) { @@ -105,26 +88,10 @@ private static void initializeGraph(Properties properties) { } // - // - private static void greetUser() { - try { - final User user = Graph.getUser(); - // For Work/school accounts, email is in mail property - // Personal accounts, email is in userPrincipalName - final String email = user.mail == null ? user.userPrincipalName : user.mail; - System.out.println("Hello, " + user.displayName + "!"); - System.out.println("Email: " + email); - } catch (Exception e) { - System.out.println("Error getting user"); - System.out.println(e.getMessage()); - } - } - // - // private static void displayAccessToken() { try { - final String accessToken = Graph.getUserToken(); + final String accessToken = Graph.getAppOnlyToken(); System.out.println("Access token: " + accessToken); } catch (Exception e) { System.out.println("Error getting access token"); @@ -133,48 +100,6 @@ private static void displayAccessToken() { } // - // - private static void listInbox() { - try { - final MessageCollectionPage messages = Graph.getInbox(); - - // Output each message's details - for (Message message: messages.getCurrentPage()) { - System.out.println("Message: " + message.subject); - System.out.println(" From: " + message.from.emailAddress.name); - System.out.println(" Status: " + (message.isRead ? "Read" : "Unread")); - System.out.println(" Received: " + message.receivedDateTime - // Values are returned in UTC, convert to local time zone - .atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime() - .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT))); - } - - final Boolean moreMessagesAvailable = messages.getNextPage() != null; - System.out.println("\nMore messages available? " + moreMessagesAvailable); - } catch (Exception e) { - System.out.println("Error getting inbox"); - System.out.println(e.getMessage()); - } - } - // - - // - private static void sendMail() { - try { - // Send mail to the signed-in user - // Get the user for their email address - final User user = Graph.getUser(); - final String email = user.mail == null ? user.userPrincipalName : user.mail; - - Graph.sendMail("Testing Microsoft Graph", "Hello world!", email); - System.out.println("\nMail sent."); - } catch (Exception e) { - System.out.println("Error sending mail"); - System.out.println(e.getMessage()); - } - } - // - // private static void listUsers() { try { diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java index 8faeea9..01e8639 100644 --- a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java @@ -4,7 +4,6 @@ // package graphapponlytutorial; -import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.function.Consumer; @@ -13,31 +12,21 @@ import com.azure.core.credential.TokenRequestContext; import com.azure.identity.ClientSecretCredential; import com.azure.identity.ClientSecretCredentialBuilder; -import com.azure.identity.DeviceCodeCredential; -import com.azure.identity.DeviceCodeCredentialBuilder; import com.azure.identity.DeviceCodeInfo; import com.microsoft.graph.authentication.TokenCredentialAuthProvider; -import com.microsoft.graph.models.BodyType; -import com.microsoft.graph.models.EmailAddress; -import com.microsoft.graph.models.ItemBody; -import com.microsoft.graph.models.Message; -import com.microsoft.graph.models.Recipient; -import com.microsoft.graph.models.User; -import com.microsoft.graph.models.UserSendMailParameterSet; import com.microsoft.graph.requests.GraphServiceClient; -import com.microsoft.graph.requests.MessageCollectionPage; import com.microsoft.graph.requests.UserCollectionPage; import okhttp3.Request; // public class Graph { - // + // private static Properties _properties; - private static DeviceCodeCredential _deviceCodeCredential; - private static GraphServiceClient _userClient; + private static ClientSecretCredential _clientSecretCredential; + private static GraphServiceClient _appClient; - public static void initializeGraphForUserAuth(Properties properties, Consumer challenge) throws Exception { + public static void initializeGraphForAppOnlyAuth(Properties properties, Consumer challenge) throws Exception { // Ensure properties isn't null if (properties == null) { throw new Exception("Properties cannot be null"); @@ -45,114 +34,6 @@ public static void initializeGraphForUserAuth(Properties properties, Consumer graphUserScopes = Arrays - .asList(properties.getProperty("app.graphUserScopes").split(",")); - - _deviceCodeCredential = new DeviceCodeCredentialBuilder() - .clientId(clientId) - .tenantId(authTenantId) - .challengeConsumer(challenge) - .build(); - - final TokenCredentialAuthProvider authProvider = - new TokenCredentialAuthProvider(graphUserScopes, _deviceCodeCredential); - - _userClient = GraphServiceClient.builder() - .authenticationProvider(authProvider) - .buildClient(); - } - // - - // - public static String getUserToken() throws Exception { - // Ensure credential isn't null - if (_deviceCodeCredential == null) { - throw new Exception("Graph has not been initialized for user auth"); - } - - final String[] graphUserScopes = _properties.getProperty("app.graphUserScopes").split(","); - - final TokenRequestContext context = new TokenRequestContext(); - context.addScopes(graphUserScopes); - - final AccessToken token = _deviceCodeCredential.getToken(context).block(); - return token.getToken(); - } - // - - // - public static User getUser() throws Exception { - // Ensure client isn't null - if (_userClient == null) { - throw new Exception("Graph has not been initialized for user auth"); - } - - return _userClient.me() - .buildRequest() - .select("displayName,mail,userPrincipalName") - .get(); - } - // - - // - public static MessageCollectionPage getInbox() throws Exception { - // Ensure client isn't null - if (_userClient == null) { - throw new Exception("Graph has not been initialized for user auth"); - } - - return _userClient.me() - .mailFolders("inbox") - .messages() - .buildRequest() - .select("from,isRead,receivedDateTime,subject") - .top(25) - .orderBy("receivedDateTime DESC") - .get(); - } - // - - // - public static void sendMail(String subject, String body, String recipient) throws Exception { - // Ensure client isn't null - if (_userClient == null) { - throw new Exception("Graph has not been initialized for user auth"); - } - - // Create a new message - final Message message = new Message(); - message.subject = subject; - message.body = new ItemBody(); - message.body.content = body; - message.body.contentType = BodyType.TEXT; - - final Recipient toRecipient = new Recipient(); - toRecipient.emailAddress = new EmailAddress(); - toRecipient.emailAddress.address = recipient; - message.toRecipients = List.of(toRecipient); - - // Send the message - _userClient.me() - .sendMail(UserSendMailParameterSet.newBuilder() - .withMessage(message) - .build()) - .buildRequest() - .post(); - } - // - - // - private static ClientSecretCredential _clientSecretCredential; - private static GraphServiceClient _appClient; - - private static void ensureGraphForAppOnlyAuth() throws Exception { - // Ensure _properties isn't null - if (_properties == null) { - throw new Exception("Properties cannot be null"); - } - if (_clientSecretCredential == null) { final String clientId = _properties.getProperty("app.clientId"); final String tenantId = _properties.getProperty("app.tenantId"); @@ -177,9 +58,29 @@ private static void ensureGraphForAppOnlyAuth() throws Exception { } // + // + public static String getAppOnlyToken() throws Exception { + // Ensure credential isn't null + if (_clientSecretCredential == null) { + throw new Exception("Graph has not been initialized for app-only auth"); + } + + final String[] graphScopes = new String[] {"https://graph.microsoft.com/.default"}; + + final TokenRequestContext context = new TokenRequestContext(); + context.addScopes(graphScopes); + + final AccessToken token = _clientSecretCredential.getToken(context).block(); + return token.getToken(); + } + // + // public static UserCollectionPage getUsers() throws Exception { - ensureGraphForAppOnlyAuth(); + // Ensure client isn't null + if (_appClient == null) { + throw new Exception("Graph has not been initialized for app-only auth"); + } return _appClient.users() .buildRequest() @@ -193,9 +94,6 @@ public static UserCollectionPage getUsers() throws Exception { // public static void makeGraphCall() { // INSERT YOUR CODE HERE - // Note: if using _appClient, be sure to call ensureGraphForAppOnlyAuth - // before using it. - // ensureGraphForAppOnlyAuth(); } // } diff --git a/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example b/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example index 4b54e97..baa4f9e 100644 --- a/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example +++ b/app-auth/graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example @@ -1,5 +1,3 @@ app.clientId=YOUR_CLIENT_ID_HERE -app.clientSecret=YOUR_CLIENT_SECRET_HERE_IF_USING_APP_ONLY -app.tenantId=YOUR_TENANT_ID_HERE_IF_USING_APP_ONLY -app.authTenant=common -app.graphUserScopes=user.read,mail.read,mail.send +app.clientSecret=YOUR_CLIENT_SECRET_HERE +app.tenantId=YOUR_TENANT_ID_HERE From e08a8a069200178d44dbddc7ee33570e628c3f18 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:33:33 -0500 Subject: [PATCH 37/55] Update READMEs --- app-auth/README.md | 71 ++++++++++----------------------------------- user-auth/README.md | 49 ++----------------------------- 2 files changed, 17 insertions(+), 103 deletions(-) diff --git a/app-auth/README.md b/app-auth/README.md index bd9d8a9..58efa9e 100644 --- a/app-auth/README.md +++ b/app-auth/README.md @@ -5,7 +5,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 [Gradle](https://gradle.org/) installed on your development machine. (**Note:** This tutorial was written with OpenJDK version 17.0.2 and Gradle 7.4.2. The steps in this guide may work with other versions, but that has not been tested.) -- A Microsoft work or school account. +- A Microsoft work or school account with the **Global administrator** role. If you don't have a Microsoft account, you can [sign up for the Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program) to get a free Microsoft 365 subscription. @@ -13,33 +13,19 @@ If you don't have a Microsoft account, you can [sign up for the Microsoft 365 De You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/get-started). -**NOTE:** If you downloaded this code from [https://developer.microsoft.com/graph/quick-start](https://developer.microsoft.com/graph/quick-start), an app registration has already been created for you. However, if you want to use the app-only portion of this sample, you will need to modify the app registration as specified in [Configure app-only auth (AAD admin center)](#configure-app-only-auth-aad-admin-center) or [Configure app-only auth (PowerShell)](#configure-app-only-auth-powershell). - ### Azure Active Directory admin center -1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**. +1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a Global administrator account. 1. Select **Azure Active Directory** in the left-hand navigation, then select **App registrations** under **Manage**. -1. Select **New registration**. Enter a name for your application, for example, `Java Graph Tutorial`. - -1. Set **Supported account types** as desired. The options are: +1. Select **New registration**. Enter a name for your application, for example, `Java App-Only Graph Tutorial`. - | Option | Who can sign in? | - |--------|------------------| - | **Accounts in this organizational directory only** | Only users in your Microsoft 365 organization | - | **Accounts in any organizational directory** | Users in any Microsoft 365 organization (work or school accounts) | - | **Accounts in any organizational directory ... and personal Microsoft accounts** | Users in any Microsoft 365 organization (work or school accounts) and personal Microsoft accounts | +1. Set **Supported account types** to **Accounts in this organizational directory only**. 1. Leave **Redirect URI** empty. -1. Select **Register**. On the application's **Overview** page, copy the value of the **Application (client) ID** and save it, you will need it in the next step. If you chose **Accounts in this organizational directory only** for **Supported account types**, also copy the **Directory (tenant) ID** and save it. - -1. Select **Authentication** under **Manage**. Locate the **Advanced settings** section and change the **Allow public client flows** toggle to **Yes**, then choose **Save**. - -#### Configure app-only auth (AAD admin center) - -> **Note:** This section requires a work/school account with the Global administrator role. You only need to complete these steps if you plan on using the app-only portions of this sample. +1. Select **Register**. On the application's **Overview** page, copy the value of the **Application (client) ID** and **Directory (tenant) ID** and save them, you will need these values in the next step. 1. Select **API permissions** under **Manage**. @@ -63,58 +49,31 @@ You can register an application using the Azure Active Directory admin center, o To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/installation) for installation instructions. -1. Open PowerShell and run the [RegisterAppForUserAuth.ps1](RegisterAppForUserAuth.ps1) file with the following command, replacing *<audience-value>* with the desired value (see table below). - - > **Note:** The RegisterAppForUserAuth.ps1 script requires a work/school account with the Application administrator, Cloud application administrator, or Global administrator role. - - ```powershell - .\RegisterAppForUserAuth.ps1 -AppName "Java Graph Tutorial" -SignInAudience - ``` - - | SignInAudience value | Who can sign in? | - |----------------------|------------------| - | `AzureADMyOrg` | Only users in your Microsoft 365 organization | - | `AzureADMultipleOrgs` | Users in any Microsoft 365 organization (work or school accounts) | - | `AzureADandPersonalMicrosoftAccount` | Users in any Microsoft 365 organization (work or school accounts) and personal Microsoft accounts | - | `PersonalMicrosoftAccount` | Only personal Microsoft accounts | - -1. Copy the **Client ID** and **Auth tenant** values from the script output. You will need these values in the next step. - - ```powershell - SUCCESS - Client ID: 2fb1652f-a9a0-4db9-b220-b224b8d9d38b - Auth tenant: common - ``` - -#### Configure app-only auth (PowerShell) - -> **Note:** This section requires a work/school account with the Global administrator role. You only need to complete these steps if you plan on using the app-only portions of this sample. - -1. Run the [UpdateAppForAppOnlyAuth.ps1](UpdateAppForAppOnlyAuth.ps1) file with the following command, replacing *<your-client-id>* with your client ID. +1. Open PowerShell and run the [RegisterAppForAppOnlyAuth.ps1](RegisterAppForAppOnlyAuth.ps1) file with the following command. ```powershell - .\UpdateAppForAppOnlyAuth.ps1 -AppId -GraphScopes "User.Read.All" + .\RegisterAppForAppOnlyAuth.ps1 -AppName "Java App-Only Graph Tutorial" -GraphScopes "User.Read.All" ``` -1. Copy the **Tenant ID** and **Client secret** values from the script output. You will need these values in the next step. +1. Copy the **Client ID**, **Tenant ID**, and **Client secret** values from the script output. You will need these values in the next step. ```powershell SUCCESS - Tenant ID: a795ad0f-7d82-4a3b-a2c0-0713ec72ade7 - Client secret: 2jv7Q~8eiOd_QafJ..... - Secret expires: 2/16/2024 9:32:09 PM + Client ID: ae2386e6-799e-4f75-b191-855d7e691c75 + Tenant ID: 5927c10a-91bd-4408-9c70-c50bce922b71 + Client secret: ... + Secret expires: 10/28/2024 5:01:45 PM ``` ## Configure the sample -1. Rename [oAuth.properties.example](./graphtutorial/app/src/main/resources/oAuth.properties.example) to `oauthProperties` and update the values according to the following table. +1. Rename [oAuth.properties.example](./graphapponlytutorial/app/src/main/resources/graphapponlytutorial/oAuth.properties.example) to `oauthProperties` and update the values according to the following table. | Setting | Value | |---------|-------| | `app.clientId` | The client ID of your app registration | - | `app.clientSecret` | The client secret (only needed if doing app-only) | - | `app.tenantId` | The tenant ID of your organization (only needed if doing app-only) | - | `app.authTenant` | If you chose the option to only allow users in your organization to sign in, change this value to your tenant ID. Otherwise leave as `common`. | + | `app.clientSecret` | The client secret | + | `app.tenantId` | The tenant ID of your organization | ## Build and run the sample diff --git a/user-auth/README.md b/user-auth/README.md index bd9d8a9..5aaf67e 100644 --- a/user-auth/README.md +++ b/user-auth/README.md @@ -13,8 +13,6 @@ If you don't have a Microsoft account, you can [sign up for the Microsoft 365 De You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/get-started). -**NOTE:** If you downloaded this code from [https://developer.microsoft.com/graph/quick-start](https://developer.microsoft.com/graph/quick-start), an app registration has already been created for you. However, if you want to use the app-only portion of this sample, you will need to modify the app registration as specified in [Configure app-only auth (AAD admin center)](#configure-app-only-auth-aad-admin-center) or [Configure app-only auth (PowerShell)](#configure-app-only-auth-powershell). - ### Azure Active Directory admin center 1. Open a browser and navigate to the [Azure Active Directory admin center](https://aad.portal.azure.com) and login using a **personal account** (aka: Microsoft Account) or **Work or School Account**. @@ -37,28 +35,6 @@ You can register an application using the Azure Active Directory admin center, o 1. Select **Authentication** under **Manage**. Locate the **Advanced settings** section and change the **Allow public client flows** toggle to **Yes**, then choose **Save**. -#### Configure app-only auth (AAD admin center) - -> **Note:** This section requires a work/school account with the Global administrator role. You only need to complete these steps if you plan on using the app-only portions of this sample. - -1. Select **API permissions** under **Manage**. - -1. Remove the default **User.Read** permission under **Configured permissions** by selecting the ellipses (**...**) in its row and selecting **Remove permission**. - -1. Select **Add a permission**, then **Microsoft Graph**. - -1. Select **Application permissions**. - -1. Select **User.Read.All**, then select **Add permissions**. - -1. Select **Grant admin consent for...**, then select **Yes** to provide admin consent for the selected permission. - -1. Select **Certificates and secrets** under **Manage**, then select **New client secret**. - -1. Enter a description, choose a duration, and select **Add**. - -1. Copy the secret from the **Value** column, you will need it in the next steps. - ### PowerShell To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/installation) for installation instructions. @@ -86,35 +62,14 @@ To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not Auth tenant: common ``` -#### Configure app-only auth (PowerShell) - -> **Note:** This section requires a work/school account with the Global administrator role. You only need to complete these steps if you plan on using the app-only portions of this sample. - -1. Run the [UpdateAppForAppOnlyAuth.ps1](UpdateAppForAppOnlyAuth.ps1) file with the following command, replacing *<your-client-id>* with your client ID. - - ```powershell - .\UpdateAppForAppOnlyAuth.ps1 -AppId -GraphScopes "User.Read.All" - ``` - -1. Copy the **Tenant ID** and **Client secret** values from the script output. You will need these values in the next step. - - ```powershell - SUCCESS - Tenant ID: a795ad0f-7d82-4a3b-a2c0-0713ec72ade7 - Client secret: 2jv7Q~8eiOd_QafJ..... - Secret expires: 2/16/2024 9:32:09 PM - ``` - ## Configure the sample -1. Rename [oAuth.properties.example](./graphtutorial/app/src/main/resources/oAuth.properties.example) to `oauthProperties` and update the values according to the following table. +1. Rename [oAuth.properties.example](./graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example) to `oauthProperties` and update the values according to the following table. | Setting | Value | |---------|-------| | `app.clientId` | The client ID of your app registration | - | `app.clientSecret` | The client secret (only needed if doing app-only) | - | `app.tenantId` | The tenant ID of your organization (only needed if doing app-only) | - | `app.authTenant` | If you chose the option to only allow users in your organization to sign in, change this value to your tenant ID. Otherwise leave as `common`. | + | `app.tenantId` | If you chose the option to only allow users in your organization to sign in, change this value to your tenant ID. Otherwise leave as `common`. | ## Build and run the sample From 1a248a39e43f5af57d357ad07aaaa7c40ae33591 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:39:03 -0500 Subject: [PATCH 38/55] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ba6debb..68616e3 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -# Microsoft Graph Training Module - Build Java apps with the Microsoft Graph Java SDK +# Build Java apps with the Microsoft Graph Java SDK - Completed project -This module will introduce you to working with the Microsoft Graph SDK to access data in Office 365 by building Java applications. +[![Java CI with Gradle](https://github.com/microsoftgraph/msgraph-training-java/actions/workflows/gradle.yml/badge.svg)](https://github.com/microsoftgraph/msgraph-training-java/actions/workflows/gradle.yml) ![License.](https://img.shields.io/badge/license-MIT-green.svg) -## Lab - Build Java apps with the Microsoft Graph Java SDK +This sample will introduce you to working with the Microsoft Graph SDK to access data in Microsoft 365 from Java applications. This code is the result of completing the [Java Microsoft Graph tutorial](https://docs.microsoft.com/graph/tutorials/java) and the [Java Microsoft Graph app-only tutorial](https://docs.microsoft.com/graph/tutorials/java-app-only). -In this lab you will create a console application using the Microsoft Authentication Library (MSAL) to access data in Office 365 using the Microsoft Graph. +## Running the sample -- [Java Microsoft Graph tutorial](https://docs.microsoft.com/graph/tutorials/java) +The code for the delegated user authentication sample is in the [user-auth](user-auth) folder. Instructions to configure and run the sample can be found in the [README](user-auth/README.md) in that folder. -## Completed sample +The code for the app-only authentication sample is in the [app-auth](app-auth) folder. Instructions to configure and run the sample can be found in the [README](app-auth/README.md) in that folder. -If you just want the completed sample generated by following this lab, you can find it here. +## Code of conduct -- [Completed project](demo) +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. ## Disclaimer From 8c2a4c20d0007b847711cb598f61d4137b247c39 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:42:11 -0500 Subject: [PATCH 39/55] Update qs.json --- qs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qs.json b/qs.json index d8d7366..e07175c 100644 --- a/qs.json +++ b/qs.json @@ -1,5 +1,5 @@ { - "sourceDirectory": "./demo", + "sourceDirectory": "./user-auth", "exampleConfigFile": "./graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example", "configFile": "oAuth.properties", "archiveFile": "JavaQuickStart.zip", From 095a3f5fbccebc4dd13cbd57bd444c9d645617b7 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:43:56 -0500 Subject: [PATCH 40/55] Update dependabot.yml --- .github/dependabot.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 51b2754..d53aba7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,10 @@ version: 2 updates: - package-ecosystem: "gradle" # See documentation for possible values - directory: "/demo/graphtutorial/" # Location of package manifests + directory: "/user-auth/graphtutorial/" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "gradle" # See documentation for possible values + directory: "/app-auth/graphapponlytutorial/" # Location of package manifests schedule: interval: "weekly" From ed4aaa7978d18b984bc437db61c8d5340e7234a3 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:46:35 -0500 Subject: [PATCH 41/55] Update gradle.yml --- .github/workflows/gradle.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index bd2f635..3eeab97 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -18,9 +18,6 @@ permissions: jobs: build: - defaults: - run: - working-directory: demo/graphtutorial runs-on: ubuntu-latest @@ -31,10 +28,17 @@ jobs: with: java-version: '17' distribution: 'temurin' - - name: Make gradlew executable - run: chmod +x ./gradlew - - name: Build with Gradle + - name: Make user app gradlew executable + run: chmod +x ./user-auth/graphtutorial/gradlew + - name: Build user app with Gradle uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee with: - build-root-directory: demo/graphtutorial + build-root-directory: user-app/graphtutorial + arguments: build + - name: Make app-only app gradlew executable + run: chmod +x ./app-auth/graphapponlytutorial/gradlew + - name: Build app-only app with Gradle + uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + with: + build-root-directory: app-auth/graphapponlytutorial arguments: build From 2a0d28d94cc2be377dfd300ded7bb74b90ec97dd Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:53:50 -0500 Subject: [PATCH 42/55] Update docs domain in links --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- README.md | 2 +- app-auth/README.md | 4 ++-- user-auth/README.md | 4 ++-- user-auth/RegisterAppForUserAuth.ps1 | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 83e3a9c..e43fcfe 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,7 +10,7 @@ assignees: '' - [ ] Downloaded from GitHub - [ ] Downloaded from the [Microsoft Graph quick start tool](https://developer.microsoft.com/graph/quick-start) -- [ ] Followed the tutorial from [Microsoft Graph tutorials](https://docs.microsoft.com/graph/tutorials) +- [ ] Followed the tutorial from [Microsoft Graph tutorials](https://learn.microsoft.com/graph/tutorials) ### Describe the bug diff --git a/README.md b/README.md index 68616e3..d7263db 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Java CI with Gradle](https://github.com/microsoftgraph/msgraph-training-java/actions/workflows/gradle.yml/badge.svg)](https://github.com/microsoftgraph/msgraph-training-java/actions/workflows/gradle.yml) ![License.](https://img.shields.io/badge/license-MIT-green.svg) -This sample will introduce you to working with the Microsoft Graph SDK to access data in Microsoft 365 from Java applications. This code is the result of completing the [Java Microsoft Graph tutorial](https://docs.microsoft.com/graph/tutorials/java) and the [Java Microsoft Graph app-only tutorial](https://docs.microsoft.com/graph/tutorials/java-app-only). +This sample will introduce you to working with the Microsoft Graph SDK to access data in Microsoft 365 from Java applications. This code is the result of completing the [Java Microsoft Graph tutorial](https://learn.microsoft.com/graph/tutorials/java) and the [Java Microsoft Graph app-only tutorial](https://learn.microsoft.com/graph/tutorials/java-app-only). ## Running the sample diff --git a/app-auth/README.md b/app-auth/README.md index 58efa9e..aef2fe0 100644 --- a/app-auth/README.md +++ b/app-auth/README.md @@ -11,7 +11,7 @@ If you don't have a Microsoft account, you can [sign up for the Microsoft 365 De ## Register an application -You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/get-started). +You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://learn.microsoft.com/graph/powershell/get-started). ### Azure Active Directory admin center @@ -47,7 +47,7 @@ You can register an application using the Azure Active Directory admin center, o ### PowerShell -To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/installation) for installation instructions. +To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://learn.microsoft.com/graph/powershell/installation) for installation instructions. 1. Open PowerShell and run the [RegisterAppForAppOnlyAuth.ps1](RegisterAppForAppOnlyAuth.ps1) file with the following command. diff --git a/user-auth/README.md b/user-auth/README.md index 5aaf67e..97d10f7 100644 --- a/user-auth/README.md +++ b/user-auth/README.md @@ -11,7 +11,7 @@ If you don't have a Microsoft account, you can [sign up for the Microsoft 365 De ## Register an application -You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/get-started). +You can register an application using the Azure Active Directory admin center, or by using the [Microsoft Graph PowerShell SDK](https://learn.microsoft.com/graph/powershell/get-started). ### Azure Active Directory admin center @@ -37,7 +37,7 @@ You can register an application using the Azure Active Directory admin center, o ### PowerShell -To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://docs.microsoft.com/graph/powershell/installation) for installation instructions. +To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not have it, see [Install the Microsoft Graph PowerShell SDK](https://learn.microsoft.com/graph/powershell/installation) for installation instructions. 1. Open PowerShell and run the [RegisterAppForUserAuth.ps1](RegisterAppForUserAuth.ps1) file with the following command, replacing *<audience-value>* with the desired value (see table below). diff --git a/user-auth/RegisterAppForUserAuth.ps1 b/user-auth/RegisterAppForUserAuth.ps1 index 45fcb35..0b8598a 100644 --- a/user-auth/RegisterAppForUserAuth.ps1 +++ b/user-auth/RegisterAppForUserAuth.ps1 @@ -21,7 +21,7 @@ param( ) # Tenant to use in authentication. -# See https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-device-code#device-authorization-request +# See https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-device-code#device-authorization-request $authTenant = switch ($SignInAudience) { "AzureADMyOrg" { "tenantId" } From cdd760e777ded95166296f8d112089cfce01148a Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 15:53:54 -0500 Subject: [PATCH 43/55] Update CONTRIBUTING.md --- CONTRIBUTING.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 17305e4..9e87646 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,15 +4,12 @@ Thank you for contributing to this project! Before submitting your pull request, ## Overview -The code in this repository serves three purposes: +The code in this repository serves two purposes: -- The Markdown files in the [tutorial](/tutorial) folder are published as a tutorial on the [Microsoft Graph tutorials](https://docs.microsoft.com/graph/tutorials) page. -- The sample project in the [demo](/demo) folder is the source for a [Microsoft Graph quick start](https://developer.microsoft.com/graph/quick-start).**\*** -- The sample project in the demo folder is also downloadable directly from GitHub and should run as-is after some simple configuration. +- The sample project in the [user-auth](/user-auth) folder is the source for a [Microsoft Graph quick start](https://developer.microsoft.com/graph/quick-start). +- The code in the [user-auth](/user-auth) and [app-auth](/app-auth) folders are directly referenced by [Microsoft Graph tutorials](https://learn.microsoft.com/graph/tutorials) -> **\*** Not all training repositories are available as quick starts (yet). - -This is important to keep in mind, because changes in one place *may* require changes in another, to keep things in sync. Whereever possible, the Markdown files refer to the source code files directly (using a custom `:::code` syntax), so that updating code in source will automatically update the code in Markdown. +This is important to keep in mind, because changes in one place *may* require changes in another, to keep things in sync. The Markdown files for the tutorials refer to the source code files directly (using a custom `:::code` syntax), so that updating code in source will automatically update the code in Markdown. ## Updating code @@ -24,7 +21,7 @@ Console.WriteLine("Hello World!"); // ``` -If you update code between these "marker" comments, the Markdown files will automatically get those changes when published to the Microsoft Graph documentation site. If you update code outside of those comments, it's very likely that you'll need to update the corresponding Markdown. +If you update code between these "marker" comments, the Markdown files will automatically get those changes when published to the Microsoft Graph documentation site. If you update code outside of those comments, it's very likely that you'll need to update the corresponding Markdown in the [Microsoft Graph training repository](https://github.com/microsoftgraph/microsoft-graph-training). ## Adding features @@ -32,11 +29,11 @@ While the enthusiasm is appreciated, please don't send pull requests to add new ## Submitting pull requests -Please submit all pull requests to the `master` branch. +Please submit all pull requests to the `main` branch. ## When do changes get published? -Publishing of updates to the [Microsoft Graph tutorials](https://docs.microsoft.com/graph/tutorials) site is not automatic. Changes must first be promoted to the `live` branch, then a build must be triggered by the site admins. This is typically done on an "as-needed" basis. +Publishing of updates to the [Microsoft Graph tutorials](https://learn.microsoft.com/graph/tutorials) site is not automatic. Changes must first be promoted to the `live` branch, then a build must be triggered by the site admins. This is typically done on an "as-needed" basis. ## Code of conduct From bee366bb561050acc8cc927931938052429dd34a Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Thu, 10 Nov 2022 16:48:19 -0500 Subject: [PATCH 44/55] Cleanup based on review --- .../app/src/main/java/graphapponlytutorial/App.java | 3 +-- .../app/src/main/java/graphapponlytutorial/Graph.java | 4 +--- .../graphtutorial/app/src/main/java/graphtutorial/Graph.java | 3 --- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java index b57ed56..c4ecf23 100644 --- a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/App.java @@ -78,8 +78,7 @@ public static void main(String[] args) { // private static void initializeGraph(Properties properties) { try { - Graph.initializeGraphForAppOnlyAuth(properties, - challenge -> System.out.println(challenge.getMessage())); + Graph.initializeGraphForAppOnlyAuth(properties); } catch (Exception e) { System.out.println("Error initializing Graph for user auth"); diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java index 01e8639..16bb8b5 100644 --- a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java @@ -6,13 +6,11 @@ import java.util.List; import java.util.Properties; -import java.util.function.Consumer; import com.azure.core.credential.AccessToken; import com.azure.core.credential.TokenRequestContext; import com.azure.identity.ClientSecretCredential; import com.azure.identity.ClientSecretCredentialBuilder; -import com.azure.identity.DeviceCodeInfo; import com.microsoft.graph.authentication.TokenCredentialAuthProvider; import com.microsoft.graph.requests.GraphServiceClient; import com.microsoft.graph.requests.UserCollectionPage; @@ -26,7 +24,7 @@ public class Graph { private static ClientSecretCredential _clientSecretCredential; private static GraphServiceClient _appClient; - public static void initializeGraphForAppOnlyAuth(Properties properties, Consumer challenge) throws Exception { + public static void initializeGraphForAppOnlyAuth(Properties properties) throws Exception { // Ensure properties isn't null if (properties == null) { throw new Exception("Properties cannot be null"); diff --git a/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java b/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java index 464eb9f..051166c 100644 --- a/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java +++ b/user-auth/graphtutorial/app/src/main/java/graphtutorial/Graph.java @@ -143,9 +143,6 @@ public static void sendMail(String subject, String body, String recipient) throw // public static void makeGraphCall() { // INSERT YOUR CODE HERE - // Note: if using _appClient, be sure to call ensureGraphForAppOnlyAuth - // before using it. - // ensureGraphForAppOnlyAuth(); } // } From 2ddc77c4af9b6b224d8036171c4c4749be5eb70e Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Fri, 11 Nov 2022 16:14:10 -0500 Subject: [PATCH 45/55] Update Graph.java --- .../app/src/main/java/graphapponlytutorial/Graph.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java index 16bb8b5..0518521 100644 --- a/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java +++ b/app-auth/graphapponlytutorial/app/src/main/java/graphapponlytutorial/Graph.java @@ -47,6 +47,7 @@ public static void initializeGraphForAppOnlyAuth(Properties properties) throws E if (_appClient == null) { final TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider( + // Use the .default scope when using app-only auth List.of("https://graph.microsoft.com/.default"), _clientSecretCredential); _appClient = GraphServiceClient.builder() @@ -63,6 +64,7 @@ public static String getAppOnlyToken() throws Exception { throw new Exception("Graph has not been initialized for app-only auth"); } + // Request the .default scope as required by app-only auth final String[] graphScopes = new String[] {"https://graph.microsoft.com/.default"}; final TokenRequestContext context = new TokenRequestContext(); From baacf9c263d33e8ed725e5b477a51504a790f9a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:05:45 +0000 Subject: [PATCH 46/55] Bump microsoft-graph from 5.40.0 to 5.41.0 in /demo/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.40.0 to 5.41.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.40.0...v5.41.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 6385602..ef0772a 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.6.1' - implementation 'com.microsoft.graph:microsoft-graph:5.40.0' + implementation 'com.microsoft.graph:microsoft-graph:5.41.0' } // From c0a9ddc5c682323bf9491c7bdb1eaefae7692338 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:09:03 +0000 Subject: [PATCH 47/55] Bump azure-identity from 1.6.1 to 1.7.0 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.6.1 to 1.7.0. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-identity_1.6.1...azure-core_1.7.0) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index ef0772a..3ab6a86 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.6.1' + implementation 'com.azure:azure-identity:1.7.0' implementation 'com.microsoft.graph:microsoft-graph:5.41.0' } // From 02dd27a7995dab25436add63b57d21c0a30ed3e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Nov 2022 14:06:27 +0000 Subject: [PATCH 48/55] Bump azure-identity from 1.7.0 to 1.7.1 in /demo/graphtutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.7.0 to 1.7.1. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-core_1.7.0...azure-identity_1.7.1) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- demo/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/graphtutorial/app/build.gradle b/demo/graphtutorial/app/build.gradle index 3ab6a86..bb8dde7 100644 --- a/demo/graphtutorial/app/build.gradle +++ b/demo/graphtutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.7.0' + implementation 'com.azure:azure-identity:1.7.1' implementation 'com.microsoft.graph:microsoft-graph:5.41.0' } // From e637170d6382e8a45b1b0cd85556bbb863b39e00 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Wed, 7 Dec 2022 11:56:36 -0500 Subject: [PATCH 49/55] Update README.md --- user-auth/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/user-auth/README.md b/user-auth/README.md index 97d10f7..fb98daa 100644 --- a/user-auth/README.md +++ b/user-auth/README.md @@ -5,9 +5,9 @@ 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 [Gradle](https://gradle.org/) installed on your development machine. (**Note:** This tutorial was written with OpenJDK version 17.0.2 and Gradle 7.4.2. 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 Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program) to get a free Microsoft 365 subscription. +- 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 Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program) to get a free Microsoft 365 subscription. ## Register an application @@ -71,7 +71,7 @@ To use PowerShell, you'll need the Microsoft Graph PowerShell SDK. If you do not | `app.clientId` | The client ID of your app registration | | `app.tenantId` | If you chose the option to only allow users in your organization to sign in, change this value to your tenant ID. Otherwise leave as `common`. | -## Build and run the sample +## Run the sample In your command-line interface (CLI), navigate to the project directory and run the following command. From f7ad1d64fc54998cf0e74e92e6149479e08e095b Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Wed, 7 Dec 2022 12:01:11 -0500 Subject: [PATCH 50/55] Update gradle.yml --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 3eeab97..a8d019f 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -33,7 +33,7 @@ jobs: - name: Build user app with Gradle uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee with: - build-root-directory: user-app/graphtutorial + build-root-directory: user-auth/graphtutorial arguments: build - name: Make app-only app gradlew executable run: chmod +x ./app-auth/graphapponlytutorial/gradlew From 902946333e05548a1d6f911e876f29a1a4a091f9 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Wed, 7 Dec 2022 12:40:47 -0500 Subject: [PATCH 51/55] Update qs.json --- qs.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qs.json b/qs.json index e07175c..572c5f8 100644 --- a/qs.json +++ b/qs.json @@ -3,5 +3,8 @@ "exampleConfigFile": "./graphtutorial/app/src/main/resources/graphtutorial/oAuth.properties.example", "configFile": "oAuth.properties", "archiveFile": "JavaQuickStart.zip", - "zipReadMe": "./README.md" + "zipReadMe": "./README.md", + "excludeFiles": [ + "user-auth/RegisterAppForUserAuth.ps1" + ] } From 25c00624eba98b6694edf66b824034ccf3255c7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 18:50:51 +0000 Subject: [PATCH 52/55] Bump microsoft-graph from 5.41.0 to 5.42.0 in /user-auth/graphtutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.41.0 to 5.42.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.41.0...v5.42.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- user-auth/graphtutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-auth/graphtutorial/app/build.gradle b/user-auth/graphtutorial/app/build.gradle index bb8dde7..e7ccf68 100644 --- a/user-auth/graphtutorial/app/build.gradle +++ b/user-auth/graphtutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.7.1' - implementation 'com.microsoft.graph:microsoft-graph:5.41.0' + implementation 'com.microsoft.graph:microsoft-graph:5.42.0' } // From fe1196a02a8c6045a7866c6668bc0243aa6132a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 18:50:58 +0000 Subject: [PATCH 53/55] Bump azure-identity in /app-auth/graphapponlytutorial Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-java) from 1.6.1 to 1.7.1. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/azure-identity_1.6.1...azure-identity_1.7.1) --- updated-dependencies: - dependency-name: com.azure:azure-identity dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app-auth/graphapponlytutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app-auth/graphapponlytutorial/app/build.gradle b/app-auth/graphapponlytutorial/app/build.gradle index 6b8adf3..0d7db26 100644 --- a/app-auth/graphapponlytutorial/app/build.gradle +++ b/app-auth/graphapponlytutorial/app/build.gradle @@ -23,7 +23,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' - implementation 'com.azure:azure-identity:1.6.1' + implementation 'com.azure:azure-identity:1.7.1' implementation 'com.microsoft.graph:microsoft-graph:5.40.0' } // From 8a382125be2617ae5151e896d77e823bcc3a5294 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 18:52:46 +0000 Subject: [PATCH 54/55] Bump microsoft-graph in /app-auth/graphapponlytutorial Bumps [microsoft-graph](https://github.com/microsoftgraph/msgraph-sdk-java) from 5.40.0 to 5.42.0. - [Release notes](https://github.com/microsoftgraph/msgraph-sdk-java/releases) - [Changelog](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/CHANGELOG.md) - [Commits](https://github.com/microsoftgraph/msgraph-sdk-java/compare/v5.40.0...v5.42.0) --- updated-dependencies: - dependency-name: com.microsoft.graph:microsoft-graph dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app-auth/graphapponlytutorial/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app-auth/graphapponlytutorial/app/build.gradle b/app-auth/graphapponlytutorial/app/build.gradle index 0d7db26..1b63305 100644 --- a/app-auth/graphapponlytutorial/app/build.gradle +++ b/app-auth/graphapponlytutorial/app/build.gradle @@ -24,7 +24,7 @@ dependencies { // This dependency is used by the application. implementation 'com.google.guava:guava:31.1-jre' implementation 'com.azure:azure-identity:1.7.1' - implementation 'com.microsoft.graph:microsoft-graph:5.40.0' + implementation 'com.microsoft.graph:microsoft-graph:5.42.0' } // From 6b17d2fe667cbc7ba1a171980cd05153b7e1a1f3 Mon Sep 17 00:00:00 2001 From: Jason Johnston Date: Fri, 9 Dec 2022 14:51:52 -0500 Subject: [PATCH 55/55] Update gradle.yml --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index a8d019f..46fc6d6 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -9,9 +9,9 @@ name: Java CI with Gradle on: push: - branches: [ main ] + branches: [ main, live ] pull_request: - branches: [ main ] + branches: [ main, live ] permissions: contents: read