├── .github ├── dependabot.yml ├── steps │ ├── 1-dependency-graph.md │ ├── 2-dependabot-alerts.md │ ├── 3-dependabot-security.md │ ├── 4-dependabot-versions.md │ └── x-review.md └── workflows │ ├── 0-start-exercise.yml │ ├── 1-dependency-graph.yml │ ├── 2-dependabot-alerts.yml │ ├── 3-dependabot-security.yml │ └── 4-dependabot-versions.yml ├── .gitignore ├── LICENSE ├── README.md └── code ├── Bootcamp.sln ├── readme.md ├── src ├── Attendee │ ├── Attendee.cs │ └── Attendee.csproj └── AttendeeSite │ ├── Attendee.js │ ├── AttendeeSite.csproj │ ├── Controllers │ └── WeatherForecastController.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── package-lock.json │ └── package.json └── test └── AttendeeTest ├── AttendeeExists.cs └── AttendeeTest.csproj /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | -------------------------------------------------------------------------------- /.github/steps/1-dependency-graph.md: -------------------------------------------------------------------------------- 1 | ## Step 1: Review and add dependencies using dependency graph 2 | 3 | **What's the big deal about securing your repository's supply chain?**: With the accelerated use of open source, most projects depend on hundreds of open-source dependencies. This poses a security problem: what if the dependencies you're using are vulnerable? You could be putting your users at risk of a supply chain attack. One of the most important things you can do to protect your supply chain is to patch your vulnerable dependencies and replace any malware. 4 | 5 | GitHub offers a range of features to help you understand the dependencies in your environment, know about vulnerabilities in those dependencies, and patch them. The supply chain features on GitHub are: 6 | 7 | - Dependency graph 8 | - Dependency review 9 | - Dependabot alerts 10 | - Dependabot updates 11 | - Dependabot security updates 12 | - Dependabot version updates 13 | 14 | **What is a dependency graph**: The dependency graph is a summary of the manifest and lock files stored in a repository and any dependencies that are submitted for the repository using the dependency submission API (beta). For each repository, it shows: 15 | 16 | - Dependencies, the ecosystems and packages it depends on 17 | - Dependents, the repositories and packages that depend on it 18 | 19 | ### :keyboard: Activity 1.1: Verify that dependency graph is enabled 20 | 21 | **We recommend opening another browser tab to work through the following activities so you can keep these instructions open for reference.** 22 | 23 | >[!NOTE] 24 | > Dependency graph is enabled by default for all new public repositories. 25 | 26 | 1. Navigate to the **Settings** tab. 27 | 1. Click **Advanced Security**. 28 | 1. Verify **Dependency Graph** is **Enabled** 29 | 30 | ### :keyboard: Activity 1.2: Add a new dependency and view your dependency graph 31 | 32 | 1. Navigate to the **Code** tab and locate the `code/src/AttendeeSite` folder. 33 | 1. Commit the following content on the `main` branch to the `package-lock.json` file as the last item on the `dependencies` map _(after the third to last bracket `}` and before the last two brackets)_ 34 | 35 | > 🪧 **Note:** You can edit and commit the file on github.com directly or hit the `.` key to open the lightweight editor to edit and commit changes. 36 | 37 | ```json 38 | , 39 | "follow-redirects": { 40 | "version": "1.14.1", 41 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", 42 | "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" 43 | } 44 | ``` 45 | 46 | 1. Navigate to the **Insights** tab. 47 | 1. Select **Dependency graph** from the side navigation bar. 48 | 1. Review all the dependencies on the **Dependencies** tab. 49 | 1. Search for `follow-redirects` and review the new dependency you just added. 50 | ![Screen Shot showing the "follow-redirects" dependency.](https://user-images.githubusercontent.com/6351798/196288729-734e3319-c5d7-4f35-a19c-676c12f0e27d.png) 51 | 1. With the new dependency added, Mona should already be busy checking your work. Give her a moment and keep watch in the comments. You will see her respond with progress info and the next lesson. 52 | -------------------------------------------------------------------------------- /.github/steps/2-dependabot-alerts.md: -------------------------------------------------------------------------------- 1 | ## Step 2: Enable and view Dependabot alerts 2 | 3 | _Nice work! :tada: You added and viewed a dependency using Dependency graph!_ 4 | 5 | Given how many dependencies our repository uses, maintaining them needs to become an automated task. Keeping our code secure is a top priority, so the first thing we need to do is set up a way to be notified when a dependency we are using is vulnerable or malware. We can do this by enabling Dependabot alerts. 6 | 7 | **What are Dependabot alerts?** 8 | 9 | Dependabot alerts tell you that your code depends on a package that is insecure. These Dependabot alerts reference the [GitHub Advisory Database](https://github.com/advisories), which contains a list of known security vulnerabilities and malware, grouped in two categories: **GitHub reviewed advisories** and **unreviewed advisories**. 10 | 11 | If your code depends on a package that has a security vulnerability, this can cause a range of problems for your project or the people who use it. You should upgrade to a secure version of the package as soon as possible. If your code uses malware, you need to replace the package with a secure alternative. 12 | 13 | Let's try this out with our newly added `follow-redirects` dependency! 14 | 15 | ### :keyboard: Activity 2.1: View security advisories in the GitHub Advisory Database 16 | 17 | 1. Navigate to [GitHub Advisory Database](https://github.com/advisories). 18 | 1. Type or paste `follow-redirects` into the advisory search box. 19 | 1. Click on any of the advisories that were found to see more information. 20 | 1. You'll see the packages, impact, patches, workaround, and references for the advisory. 21 | 22 | Notice the long list of advisories for our dependency! This can look scary but it's actually a good thing. It means that our dependency is actively being maintained and patches are being pushed to remove the vulnerability. If we had Dependabot alerts enabled, we could receive alerts when we need to update a dependency and act promptly to secure them. 23 | 24 | Let's enable Dependabot alerts on our repository! 25 | 26 | ### :keyboard: Activity 2.2: Enable Dependabot alerts 27 | 28 | 1. Navigate to the **Settings** tab. 29 | 1. Display the settings for **Advanced Security**. 30 | 1. **Enable** Dependabot alerts. 31 | 1. **Wait about 60 seconds for Dependabot to check for alerts.** 32 | 1. Navigate to the **Security** tab. 33 | 1. Under "Vulnerability alerts" in the side bar, select **Dependabot** to view a list of the Dependabot alerts for the default branch. 34 | 35 | Dependabot has alerted us to vulnerabilities in the dependencies that we use. We can also use Dependabot to help us address these vulnerabilities by creating pull requests to update the dependency to a safe version. 36 | 37 | Let's see how this would work by using Dependabot to create a pull request for one of the alerts! 38 | 39 | ### :keyboard: Activity 2.3: Create a pull request based on a Dependabot alert 40 | 41 | 1. In the list of Dependabot alerts, click the "Prototype Pollution in minimist" to display more information. 42 | 1. Click the **Create Dependabot security update** button to create a pull request to update the dependency. This could take up to 2 minutes. 43 | 1. When the pull request is open, the alert page is updated to show a **Review security update** button. 44 | 1. Click the **Review security update** button to display the pull request. 45 | - You can view the pull request and **Files changed** tab to review the update. 46 | 1. Navigate back to the **Conversation** tab and merge the pull request. 47 | 1. With the pull request merged, Mona should already be busy checking your work. Give her a moment and keep watch in the comments. You will see her respond with progress info and the next lesson. -------------------------------------------------------------------------------- /.github/steps/3-dependabot-security.md: -------------------------------------------------------------------------------- 1 | ## Step 3: Enable and trigger Dependabot security updates 2 | 3 | _Nice work enabling, viewing, and creating Dependabot alerts :sparkles:_ 4 | 5 | Enabling Dependabot alerts on our repository was a great step toward improving our code security, but we still had to manually select an alert and then manually select the option to create the pull request. It would be nice to further improve the automation and maintenance of our dependencies! Well, with Dependabot security updates, we can do just that. 6 | 7 | **What are Dependabot security updates?** 8 | 9 | When this feature is enabled, Dependabot detects *and* fixes vulnerable dependencies for you by opening pull requests automatically to resolve Dependabot alerts. 10 | 11 | We manually created a pull request to fix the "Prototype Pollution in minimist" alert, but let's enable Dependabot security updates to automate this process for future alerts! 12 | 13 | ### :keyboard: Activity 3.1: Enable and trigger Dependabot security updates 14 | 15 | 1. Navigate to the **Settings** tab and select **Advanced Security**. 16 | 1. Enable **Dependabot security updates**. You may need to wait 30-60 seconds before you see any new pull requests. 17 | 1. Navigate to the **Pull requests** repository tab to view the what Dependabot has found. 18 | 1. Find the new pull request that requests to patch the **axios** dependency. 19 | 1. Review and merge the pull request. 20 | 1. With the pull request merged, Mona should already be busy checking your work. Give her a moment and keep watch in the comments. You will see her respond with progress info and the next lesson. -------------------------------------------------------------------------------- /.github/steps/4-dependabot-versions.md: -------------------------------------------------------------------------------- 1 | ## Step 4: Enable and trigger Dependabot version updates 2 | 3 | _Nicely done!_ :partying_face: 4 | 5 | You now have automated the process for Dependabot to alert you to vulnerabilities with your dependencies and to create pull requests to update them to secure versions! At this point, you only need to review the pull request and then merge it to stay on top of security problems with Dependencies. 6 | 7 | > [!NOTE] 8 | > Did you notice that there were several pull requests suggested by Dependabot? You only merged the one related to the **axios** dependency, but the others disappeared from the **Pull requests** panel. That's because the upgrade of the axios dependency triggered changes of other transitive dependencies, that might be either removed or updated to other versions. Whenever there is a change in your dependency graph, Dependabot will automatically review the existing pull requests and close the ones that are no longer relevant. So don't merge everything at once, let Dependabot do the job for you! 9 | Screenshot showing that the axios PR was merged and that the 2 others were closed 10 | 11 | 12 | The security updates feature helps automate the process to resolve alerts, but what about just keeping up-to-date with version updates? We can also automate pull request generation for updated versions of dependencies using the Dependabot version updates feature. 13 | 14 | **What are Dependabot version updates?**: In addition to security alerts, Dependabot can also take the effort out of maintaining your dependencies. You can use it to ensure that your repository automatically keeps up with the latest releases of the packages and applications it depends on. Similar to security alerts, Dependabot will identify an outdated dependency and create a pull request to update the manifest to the latest version of the dependency. 15 | 16 | Let's see how this works! 17 | 18 | ### :keyboard: Activity 4.1: Enable and trigger Dependabot version updates 19 | 20 | 1. Navigate to the **Settings** tab and select **Advanced Security**. 21 | 1. Locate **Dependabot version updates** and click **Configure** to open a new file editor with pre-poplulated contents. The file is called `dependabot.yml`. 22 | 1. Notice that the file is prepopulated to update the GitHub actions in the repository, the `github-actions` package ecosystem. 23 | 1. Edit your `dependabot.yml` configuration file to include another entry. It should look like: 24 | 25 | ```yaml 26 | version: 2 27 | updates: 28 | - package-ecosystem: "github-actions" 29 | directory: "/" 30 | schedule: 31 | interval: "monthly" 32 | - package-ecosystem: "nuget" 33 | directory: "/code/" 34 | schedule: 35 | interval: "weekly" 36 | ``` 37 | 38 | > 💡 **Tip:** While, you can edit and commit a file directly on github.com, you can also press the period key `.` to open a lightweight VS Code editor directly in browser. 39 | 40 | 1. Commit your changes directly to the `main` branch. 41 | 1. With the configuration file updated, Mona should already be busy checking your work. Give her a moment and keep watch in the comments. You will see her respond with progress info and the next lesson. 42 | 43 | You have now configured Dependabot version updates to run and check for updates as follows: 44 | 45 | - Check once a month for updates to GitHub Actions and create pull requests to update any that are out of date. 46 | - Check once a week for updates to .NET packages and create pull requests to update any that are out of date. By default, this check runs on a Monday, to run the check on a different day, see [schedule.day](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#scheduleday). 47 | -------------------------------------------------------------------------------- /.github/steps/x-review.md: -------------------------------------------------------------------------------- 1 | ## Review 2 | 3 | _Congratulations, you've completed this exercise and learned a lot securing your supply chain!_ 4 | 5 | celebrate 6 | Here's a recap of all the tasks you've accomplished in your repository: 7 | 8 | - You've learned how to view and use dependency graph. 9 | - You've learned how to enable and use Dependabot alerts. 10 | - You've learned how to enable and use Dependabot security updates. 11 | - You've learned how to enable and use Dependabot version updates. 12 | 13 | ### Additional learning and resources 14 | 15 | - [Dependency graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph) 16 | - [Exploring the dependencies of a repository](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exploring-the-dependencies-of-a-repository) 17 | - [About supply chain security](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-supply-chain-security) 18 | - [Dependabot alerts](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/about-dependabot-alerts) 19 | - [GitHub Advisory Database](https://docs.github.com/en/code-security/dependabot/dependabot-alerts/browsing-security-advisories-in-the-github-advisory-database) 20 | 21 | ### What's next? 22 | 23 | - Learn more about securing your supply chain by reading: [Securing your supply chain](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-supply-chain-security). 24 | - Check out other security focused [GitHub Skills exercises](https://skills.github.com/#code-security-and-analysis). 25 | - [Read the Get started with GitHub docs](https://docs.github.com/en/get-started). 26 | - To find projects to contribute to, check out [GitHub Explore](https://github.com/explore). 27 | -------------------------------------------------------------------------------- /.github/workflows/0-start-exercise.yml: -------------------------------------------------------------------------------- 1 | name: Step 0 # Start Exercise 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: write # Update Readme 10 | actions: write # Disable/enable workflows 11 | issues: write # Create issue and comment on issues 12 | 13 | env: 14 | STEP_1_FILE: ".github/steps/1-dependency-graph.md" 15 | 16 | jobs: 17 | disable_workflows: 18 | name: Disable workflows 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | 25 | - name: Disable all workflows 26 | run: | 27 | workflows=$(git ls-files .github/workflows | grep -E '\.yml$|\.yaml$') 28 | for workflow in $workflows; do 29 | workflow_name=$(basename "$workflow") 30 | gh workflow disable "$workflow_name" || true 31 | done 32 | env: 33 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | 35 | start_exercise: 36 | if: | 37 | !github.event.repository.is_template 38 | name: Start Exercise 39 | uses: skills/exercise-toolkit/.github/workflows/start-exercise.yml@v0.3.0 40 | with: 41 | exercise-title: "Secure your Repository's Supply Chain" 42 | intro-message: "Let's explore how to secure your repository's supply chain, understand dependencies in your environment, and find vulnerabilities in those dependencies and patch them. 💻✨" 43 | 44 | post_next_step_content: 45 | name: Post next step content 46 | runs-on: ubuntu-latest 47 | needs: [start_exercise] 48 | env: 49 | ISSUE_URL: ${{ needs.start_exercise.outputs.issue-url }} 50 | 51 | steps: 52 | - name: Checkout 53 | uses: actions/checkout@v4 54 | 55 | - name: Get response templates 56 | uses: actions/checkout@v4 57 | with: 58 | repository: skills/exercise-toolkit 59 | path: exercise-toolkit 60 | ref: v0.3.0 61 | 62 | - name: Build comment - add step content 63 | id: build-comment 64 | uses: skills/action-text-variables@v2 65 | with: 66 | template-file: "${{ env.STEP_1_FILE }}" 67 | template-vars: | 68 | full_repo_name: "${{ github.repository }}" 69 | 70 | - name: Create comment - add step content 71 | run: | 72 | gh issue comment "$ISSUE_URL" \ 73 | --body "$ISSUE_BODY" 74 | env: 75 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 76 | ISSUE_BODY: ${{ steps.build-comment.outputs.updated-text }} 77 | 78 | - name: Create comment - watching for progress 79 | run: | 80 | gh issue comment "$ISSUE_URL" \ 81 | --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md 82 | env: 83 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 84 | 85 | - name: Disable current workflow and enable next one 86 | run: | 87 | gh workflow enable "Step 1" 88 | env: 89 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/1-dependency-graph.yml: -------------------------------------------------------------------------------- 1 | name: Step 1 # Review add dependency graph 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "code/src/AttendeeSite/**" 9 | 10 | permissions: 11 | contents: read 12 | actions: write 13 | issues: write 14 | 15 | env: 16 | STEP_2_FILE: ".github/steps/2-dependabot-alerts.md" 17 | FOLLOW_REDIRECTS_FILE: "code/src/AttendeeSite/package-lock.json" 18 | FOLLOW_REDIRECTS_KEYPHRASE: "1\\.14\\.1" 19 | 20 | jobs: 21 | find_exercise: 22 | name: Find Exercise Issue 23 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0 24 | if: | 25 | github.run_number != 1 26 | 27 | check_step_work: 28 | name: Check step work 29 | runs-on: ubuntu-latest 30 | needs: find_exercise 31 | if: | 32 | !github.event.repository.is_template 33 | env: 34 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 35 | 36 | steps: 37 | - name: Checkout 38 | uses: actions/checkout@v4 39 | 40 | - name: Get response templates 41 | uses: actions/checkout@v4 42 | with: 43 | repository: skills/exercise-toolkit 44 | path: exercise-toolkit 45 | ref: v0.3.0 46 | 47 | - name: Update comment - checking work 48 | run: | 49 | gh issue comment "$ISSUE_URL" \ 50 | --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \ 51 | --edit-last 52 | env: 53 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | 55 | # START: Check practical exercise 56 | 57 | # Search for the comment about registration validation 58 | - name: Check package-lock.json 59 | run: | 60 | # File and expected phrase 61 | file="$FOLLOW_REDIRECTS_FILE" 62 | keyphrase="$FOLLOW_REDIRECTS_KEYPHRASE" 63 | 64 | # Fail the workflow if the file content is missing 65 | if ! grep -q "$keyphrase" "$file"; then 66 | message="The follow-redirects version $keyphrase is not present in file $file. Please try again." 67 | gh issue comment "$ISSUE_URL" \ 68 | --body "$message" \ 69 | --edit-last 70 | exit 1 71 | fi 72 | env: 73 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 74 | 75 | # END: Check practical exercise 76 | 77 | - name: Build message - step finished 78 | id: build-message-step-finish 79 | uses: skills/action-text-variables@v2 80 | with: 81 | template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md 82 | template-vars: | 83 | next_step_number: "2" 84 | 85 | - name: Update comment - step finished 86 | run: | 87 | gh issue comment "$ISSUE_URL" \ 88 | --body "${{ steps.build-message-step-finish.outputs.updated-text }}" \ 89 | --edit-last 90 | env: 91 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 92 | 93 | post_next_step_content: 94 | name: Post next step content 95 | needs: [find_exercise, check_step_work] 96 | runs-on: ubuntu-latest 97 | env: 98 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 99 | 100 | steps: 101 | - name: Checkout 102 | uses: actions/checkout@v4 103 | 104 | - name: Get response templates 105 | uses: actions/checkout@v4 106 | with: 107 | repository: skills/exercise-toolkit 108 | path: exercise-toolkit 109 | ref: v0.3.0 110 | 111 | - name: Build comment - add step content 112 | id: build-comment 113 | uses: skills/action-text-variables@v2 114 | with: 115 | template-file: "${{ env.STEP_2_FILE }}" 116 | template-vars: | 117 | full_repo_name: "${{ github.repository }}" 118 | 119 | - name: Create comment - add step content 120 | run: | 121 | gh issue comment "$ISSUE_URL" \ 122 | --body "$ISSUE_BODY" 123 | env: 124 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 125 | ISSUE_BODY: ${{ steps.build-comment.outputs.updated-text }} 126 | 127 | - name: Create comment - watching for progress 128 | run: | 129 | gh issue comment "$ISSUE_URL" \ 130 | --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md 131 | env: 132 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 133 | 134 | - name: Disable current workflow and enable next one 135 | run: | 136 | gh workflow disable "Step 1" 137 | gh workflow enable "Step 2" 138 | env: 139 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/2-dependabot-alerts.yml: -------------------------------------------------------------------------------- 1 | name: Step 2 # Dependency Alerts 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "code/src/AttendeeSite/**" 9 | 10 | permissions: 11 | contents: read 12 | actions: write 13 | issues: write 14 | 15 | env: 16 | STEP_3_FILE: ".github/steps/3-dependabot-security.md" 17 | PACKAGE_JSON: "code/src/AttendeeSite/package.json" 18 | PACKAGE_LOCK_JSON: "code/src/AttendeeSite/package-lock.json" 19 | 20 | jobs: 21 | find_exercise: 22 | name: Find Exercise Issue 23 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0 24 | if: | 25 | github.run_number != 1 26 | 27 | check_step_work: 28 | name: Check step work 29 | runs-on: ubuntu-latest 30 | needs: find_exercise 31 | if: | 32 | !github.event.repository.is_template 33 | env: 34 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 35 | 36 | steps: 37 | - name: Checkout 38 | uses: actions/checkout@v4 39 | 40 | - name: Get response templates 41 | uses: actions/checkout@v4 42 | with: 43 | repository: skills/exercise-toolkit 44 | path: exercise-toolkit 45 | ref: v0.3.0 46 | 47 | - name: Update comment - checking work 48 | run: | 49 | gh issue comment "$ISSUE_URL" \ 50 | --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \ 51 | --edit-last 52 | env: 53 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | 55 | # START: Check practical exercise 56 | 57 | - name: Check package.json and package-lock.json for minimist version other than 1.2.5 58 | id: check-user-work 59 | run: | 60 | # Checks to perform 61 | checks='{ 62 | "package_json": { 63 | "name": "package.json", 64 | "passed": true, 65 | "message": "" 66 | }, 67 | "package_lock_json": { 68 | "name": "package-lock.json", 69 | "passed": true, 70 | "message": "" 71 | } 72 | }' 73 | 74 | # Check for minimist version in package.json 75 | file="$PACKAGE_JSON" 76 | keyphrase="\"minimist\":[\ \\n\\r\\t]*\"\\^(?!1\\.2\\.[0-5])(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?\"" 77 | minimum_occurrences=1 78 | found_occurrences=$(grep -o "$keyphrase" "$file" | wc -l) 79 | if [ "$found_occurrences" -lt "$minimum_occurrences" ]; then 80 | checks=$(echo $checks | jq '.package_json.passed = false') 81 | checks=$(echo $checks | jq '.package_json.message = "Please update package.json to use a valid minimist version."') 82 | fi 83 | 84 | # Check for minimist version in package-lock.json 85 | file="$PACKAGE_LOCK_JSON" 86 | keyphrase="minimist-(?!1\\.2\\.[0-5])(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?" 87 | minimum_occurrences=1 88 | found_occurrences=$(grep -o "$keyphrase" "$file" | wc -l) 89 | if [ "$found_occurrences" -lt "$minimum_occurrences" ]; then 90 | checks=$(echo $checks | jq '.package_lock_json.passed = false') 91 | checks=$(echo $checks | jq '.package_lock_json.message = "Please update package-lock.json to use a valid minimist version."') 92 | fi 93 | 94 | # Verify all checks passed 95 | passed=$(echo $checks | jq '. | all(.passed?)') 96 | 97 | # Flatten to an array for returning. Allows iteration during rendering. 98 | results=$(echo $checks | jq 'to_entries | map({name: .key} + .value)') 99 | 100 | # Save pass status to output 101 | echo "passed=$passed" >> $GITHUB_OUTPUT 102 | 103 | # Save results to output 104 | echo 'results<> $GITHUB_OUTPUT 105 | echo $results >> $GITHUB_OUTPUT 106 | echo 'EOF' >> $GITHUB_OUTPUT 107 | env: 108 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 109 | 110 | # END: Check practical exercise 111 | 112 | - name: Build message - step finished 113 | id: build-message-step-finish 114 | uses: skills/action-text-variables@v2 115 | with: 116 | template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md 117 | template-vars: | 118 | next_step_number: "3" 119 | 120 | - name: Update comment - step finished 121 | run: | 122 | gh issue comment "$ISSUE_URL" \ 123 | --body "${{ steps.build-message-step-finish.outputs.updated-text }}" \ 124 | --edit-last 125 | env: 126 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 127 | 128 | post_next_step_content: 129 | name: Post next step content 130 | needs: [find_exercise, check_step_work] 131 | runs-on: ubuntu-latest 132 | env: 133 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 134 | 135 | steps: 136 | - name: Checkout 137 | uses: actions/checkout@v4 138 | 139 | - name: Get response templates 140 | uses: actions/checkout@v4 141 | with: 142 | repository: skills/exercise-toolkit 143 | path: exercise-toolkit 144 | ref: v0.3.0 145 | 146 | - name: Build comment - add step content 147 | id: build-comment 148 | uses: skills/action-text-variables@v2 149 | with: 150 | template-file: "${{ env.STEP_3_FILE }}" 151 | template-vars: | 152 | full_repo_name: "${{ github.repository }}" 153 | 154 | - name: Create comment - add step content 155 | run: | 156 | gh issue comment "$ISSUE_URL" \ 157 | --body "$ISSUE_BODY" 158 | env: 159 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 160 | ISSUE_BODY: ${{ steps.build-comment.outputs.updated-text }} 161 | 162 | - name: Create comment - watching for progress 163 | run: | 164 | gh issue comment "$ISSUE_URL" \ 165 | --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md 166 | env: 167 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 168 | 169 | - name: Disable current workflow and enable next one 170 | run: | 171 | gh workflow disable "Step 2" 172 | gh workflow enable "Step 3" 173 | env: 174 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/3-dependabot-security.yml: -------------------------------------------------------------------------------- 1 | name: Step 3 # Dependabot Security Updates 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - "code/src/AttendeeSite/**" 9 | 10 | permissions: 11 | contents: read 12 | actions: write 13 | issues: write 14 | 15 | env: 16 | STEP_4_FILE: ".github/steps/4-dependabot-versions.md" 17 | PACKAGE_JSON: "code/src/AttendeeSite/package.json" 18 | PACKAGE_LOCK_JSON: "code/src/AttendeeSite/package-lock.json" 19 | 20 | jobs: 21 | find_exercise: 22 | name: Find Exercise Issue 23 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0 24 | if: | 25 | github.run_number != 1 26 | 27 | check_step_work: 28 | name: Check step work 29 | runs-on: ubuntu-latest 30 | needs: find_exercise 31 | if: | 32 | !github.event.repository.is_template 33 | env: 34 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 35 | 36 | steps: 37 | - name: Checkout 38 | uses: actions/checkout@v4 39 | 40 | - name: Get response templates 41 | uses: actions/checkout@v4 42 | with: 43 | repository: skills/exercise-toolkit 44 | path: exercise-toolkit 45 | ref: v0.3.0 46 | 47 | - name: Update comment - checking work 48 | run: | 49 | gh issue comment "$ISSUE_URL" \ 50 | --body-file exercise-toolkit/markdown-templates/step-feedback/checking-work.md \ 51 | --edit-last 52 | env: 53 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | 55 | # START: Check practical exercise 56 | 57 | # Verify the PR added the dependabot changes. 58 | - name: Check package.json and package-lock.json for axios version other than 0.21.1 59 | id: check-axios-version 60 | run: | 61 | # Checks to perform 62 | checks='{ 63 | "package_json": { 64 | "name": "package.json", 65 | "passed": true, 66 | "message": "" 67 | }, 68 | "package_lock_json": { 69 | "name": "package-lock.json", 70 | "passed": true, 71 | "message": "" 72 | } 73 | }' 74 | 75 | # Check for minimist version in package.json 76 | file="$PACKAGE_JSON" 77 | keyphrase="\"axios\":[\ \\n\\r\\t]*\"\\^(?!0\\.21\\.[01])(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?\"" 78 | minimum_occurrences=1 79 | found_occurrences=$(grep -o "$keyphrase" "$file" | wc -l) 80 | if [ "$found_occurrences" -lt "$minimum_occurrences" ]; then 81 | checks=$(echo $checks | jq '.package_json.passed = false') 82 | checks=$(echo $checks | jq '.package_json.message = "Please update package.json to use a valid axios version."') 83 | fi 84 | 85 | # Check for minimist version in package-lock.json 86 | file="$PACKAGE_LOCK_JSON" 87 | keyphrase="axios-(?!0\\.21\\.[01])(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?" 88 | minimum_occurrences=1 89 | found_occurrences=$(grep -o "$keyphrase" "$file" | wc -l) 90 | if [ "$found_occurrences" -lt "$minimum_occurrences" ]; then 91 | checks=$(echo $checks | jq '.package_lock_json.passed = false') 92 | checks=$(echo $checks | jq '.package_lock_json.message = "Please update package-lock.json to use a valid axios version."') 93 | fi 94 | 95 | # Verify all checks passed 96 | passed=$(echo $checks | jq '. | all(.passed?)') 97 | 98 | # Flatten to an array for returning. Allows iteration during rendering. 99 | results=$(echo $checks | jq 'to_entries | map({name: .key} + .value)') 100 | 101 | # Save pass status to output 102 | echo "passed=$passed" >> $GITHUB_OUTPUT 103 | 104 | # Save results to output 105 | echo 'results<> $GITHUB_OUTPUT 106 | echo $results >> $GITHUB_OUTPUT 107 | echo 'EOF' >> $GITHUB_OUTPUT 108 | env: 109 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 110 | 111 | # END: Check practical exercise 112 | 113 | - name: Build message - step finished 114 | id: build-message-step-finish 115 | uses: skills/action-text-variables@v2 116 | with: 117 | template-file: exercise-toolkit/markdown-templates/step-feedback/step-finished-prepare-next-step.md 118 | template-vars: | 119 | next_step_number: "4" 120 | 121 | - name: Update comment - step finished 122 | run: | 123 | gh issue comment "$ISSUE_URL" \ 124 | --body "${{ steps.build-message-step-finish.outputs.updated-text }}" \ 125 | --edit-last 126 | env: 127 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 128 | 129 | post_next_step_content: 130 | name: Post next step content 131 | needs: [find_exercise, check_step_work] 132 | runs-on: ubuntu-latest 133 | env: 134 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 135 | 136 | steps: 137 | - name: Checkout 138 | uses: actions/checkout@v4 139 | 140 | - name: Get response templates 141 | uses: actions/checkout@v4 142 | with: 143 | repository: skills/exercise-toolkit 144 | path: exercise-toolkit 145 | ref: v0.3.0 146 | 147 | - name: Build comment - add step content 148 | id: build-comment 149 | uses: skills/action-text-variables@v2 150 | with: 151 | template-file: "${{ env.STEP_4_FILE }}" 152 | template-vars: | 153 | full_repo_name: "${{ github.repository }}" 154 | 155 | - name: Create comment - add step content 156 | run: | 157 | gh issue comment "$ISSUE_URL" \ 158 | --body "$ISSUE_BODY" 159 | env: 160 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 161 | ISSUE_BODY: ${{ steps.build-comment.outputs.updated-text }} 162 | 163 | - name: Create comment - watching for progress 164 | run: | 165 | gh issue comment "$ISSUE_URL" \ 166 | --body-file exercise-toolkit/markdown-templates/step-feedback/watching-for-progress.md 167 | env: 168 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 169 | 170 | - name: Disable current workflow and enable next one 171 | run: | 172 | gh workflow disable "Step 3" 173 | gh workflow enable "Step 4" 174 | env: 175 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 176 | -------------------------------------------------------------------------------- /.github/workflows/4-dependabot-versions.yml: -------------------------------------------------------------------------------- 1 | name: Step 4 # Add Dependabot version updates 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - ".github/dependabot.yml" 9 | 10 | permissions: 11 | contents: write 12 | actions: write 13 | issues: write 14 | 15 | env: 16 | REVIEW_FILE: ".github/steps/x-review.md" 17 | DEPENDABOT_FILE: ".github/dependabot.yml" 18 | DEPENDABOT_KEYPHRASE: "nuget" 19 | 20 | jobs: 21 | find_exercise: 22 | name: Find Exercise Issue 23 | uses: skills/exercise-toolkit/.github/workflows/find-exercise-issue.yml@v0.3.0 24 | if: | 25 | github.run_number != 1 26 | 27 | check_step_work: 28 | name: Check step work 29 | needs: find_exercise 30 | runs-on: ubuntu-latest 31 | if: | 32 | !github.event.repository.is_template 33 | env: 34 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 35 | 36 | steps: 37 | - name: Checkout 38 | uses: actions/checkout@v4 39 | 40 | - name: Get response templates 41 | uses: actions/checkout@v4 42 | with: 43 | repository: skills/exercise-toolkit 44 | path: exercise-toolkit 45 | ref: v0.3.0 46 | 47 | # START: Check practical exercise 48 | 49 | # Search for the comment about registration validation 50 | - name: Check .github/dependabot.yml 51 | run: | 52 | # File and expected phrase 53 | file="$DEPENDABOT_FILE" 54 | keyphrase="$DEPENDABOT_KEYPHRASE" 55 | 56 | # Fail the workflow if the file content is missing 57 | if ! grep -q "$keyphrase" "$file"; then 58 | message="$keyphrase is not present in file $file. Please try again." 59 | gh issue comment "$ISSUE_URL" \ 60 | --body "$message" \ 61 | --edit-last 62 | exit 1 63 | fi 64 | env: 65 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 66 | 67 | # END: Check practical exercise 68 | 69 | - name: Update comment - step finished - final review next 70 | run: | 71 | gh issue comment "$ISSUE_URL" \ 72 | --body-file exercise-toolkit/markdown-templates/step-feedback/lesson-review.md \ 73 | --edit-last 74 | env: 75 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 76 | 77 | post_review_content: 78 | name: Post review content 79 | needs: [find_exercise, check_step_work] 80 | runs-on: ubuntu-latest 81 | if: | 82 | !github.event.repository.is_template 83 | env: 84 | ISSUE_URL: ${{ needs.find_exercise.outputs.issue-url }} 85 | 86 | steps: 87 | - name: Checkout 88 | uses: actions/checkout@v4 89 | 90 | - name: Create comment - add review content 91 | run: | 92 | gh issue comment "$ISSUE_URL" \ 93 | --body-file ${{ env.REVIEW_FILE }} 94 | env: 95 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 96 | 97 | finish_exercise: 98 | name: Finish Exercise 99 | needs: [find_exercise, post_review_content] 100 | uses: skills/exercise-toolkit/.github/workflows/finish-exercise.yml@v0.3.0 101 | with: 102 | issue-url: ${{ needs.find_exercise.outputs.issue-url }} 103 | 104 | disable_workflow: 105 | name: Disable this workflow 106 | needs: [find_exercise, post_review_content] 107 | runs-on: ubuntu-latest 108 | 109 | steps: 110 | - name: Checkout 111 | uses: actions/checkout@v4 112 | - name: Disable current workflow 113 | run: gh workflow disable "${{github.workflow}}" 114 | env: 115 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 116 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | *.sql 27 | *.sqlite 28 | 29 | # OS generated files # 30 | ###################### 31 | .DS_Store 32 | .DS_Store? 33 | ._* 34 | .Spotlight-V100 35 | .Trashes 36 | ehthumbs.db 37 | Thumbs.db 38 | 39 | # Sample payload files # 40 | ##################### 41 | # These files are used for testing and should not be included in the repository 42 | .temp/** -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 GitHub Skills 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Secure your repository's supply chain 2 | 3 | _Secure your supply chain, understand dependencies in your environment, know about vulnerabilities in those dependencies and patch them._ 4 | 5 | ## Welcome 6 | 7 | GitHub helps you secure your supply chain, from understanding the dependencies in your environment, to knowing about vulnerabilities in those dependencies and patching them. 8 | 9 | - **Who this is for**: Developers, DevOps Engineers, Site Reliability Engineers, Security experts 10 | - **What you'll learn**: How to view repository dependencies, view Dependabot alerts, and enable Dependabot security and version updates 11 | - **What you'll build**: Repository dependencies, Dependabot alerts, pull requests to fix dependencies and version updates 12 | - **Prerequisites**: None 13 | - **Timing**: This exercise can be completed in under an hour 14 | 15 | In this exercise, you will explore: 16 | 17 | 1. Dependency graph 18 | 2. Dependency alerts 19 | 3. Dependency security updates 20 | 4. Dependency versions updates 21 | 22 | ### How to start this exercise 23 | 24 | Simply copy the exercise to your account, then give your favorite Octocat (Mona) **about 20 seconds** to prepare the first lesson, then **refresh the page**. 25 | 26 | [![](https://img.shields.io/badge/Copy%20Exercise-%E2%86%92-1f883d?style=for-the-badge&logo=github&labelColor=197935)](https://github.com/new?template_owner=skills&template_name=secure-repository-supply-chain&owner=%40me&name=skills-secure-repository-supply-chain&description=Exercise:+Secure+your+Repository+Supply+Chain&visibility=public) 27 | 28 |
29 | Having trouble? 🤷
30 | 31 | When copying the exercise, we recommend the following settings: 32 | 33 | - For owner, choose your personal account or an organization to host the repository. 34 | 35 | - We recommend creating a public repository, since private repositories will use Actions minutes. 36 | 37 | If the exercise isn't ready in 20 seconds, please check the [Actions](../../actions) tab. 38 | 39 | - Check to see if a job is running. Sometimes it simply takes a bit longer. 40 | 41 | - If the page shows a failed job, please submit an issue. Nice, you found a bug! 🐛 42 | 43 |
44 | 45 | --- 46 | 47 | © 2025 GitHub • [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) • [MIT License](https://gh.io/mit) 48 | -------------------------------------------------------------------------------- /code/Bootcamp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30114.105 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B26D43AA-4A35-4035-9E99-48EF9A3E64DD}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Attendee", "src\Attendee\Attendee.csproj", "{2804EC63-670C-4970-85E4-2A63C9327FF8}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{348A52EC-7046-4D1A-88DB-55B025C2BB68}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AttendeeTest", "test\AttendeeTest\AttendeeTest.csproj", "{DED76823-F195-46D4-8509-5692E3431D53}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AttendeeSite", "src\AttendeeSite\AttendeeSite.csproj", "{024C85A1-1144-4D1A-ADCC-010845B94620}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Debug|x64 = Debug|x64 20 | Debug|x86 = Debug|x86 21 | Release|Any CPU = Release|Any CPU 22 | Release|x64 = Release|x64 23 | Release|x86 = Release|x86 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x64.ActiveCfg = Debug|Any CPU 32 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x64.Build.0 = Debug|Any CPU 33 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x86.ActiveCfg = Debug|Any CPU 34 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Debug|x86.Build.0 = Debug|Any CPU 35 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x64.ActiveCfg = Release|Any CPU 38 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x64.Build.0 = Release|Any CPU 39 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x86.ActiveCfg = Release|Any CPU 40 | {2804EC63-670C-4970-85E4-2A63C9327FF8}.Release|x86.Build.0 = Release|Any CPU 41 | {DED76823-F195-46D4-8509-5692E3431D53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {DED76823-F195-46D4-8509-5692E3431D53}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {DED76823-F195-46D4-8509-5692E3431D53}.Debug|x64.ActiveCfg = Debug|Any CPU 44 | {DED76823-F195-46D4-8509-5692E3431D53}.Debug|x64.Build.0 = Debug|Any CPU 45 | {DED76823-F195-46D4-8509-5692E3431D53}.Debug|x86.ActiveCfg = Debug|Any CPU 46 | {DED76823-F195-46D4-8509-5692E3431D53}.Debug|x86.Build.0 = Debug|Any CPU 47 | {DED76823-F195-46D4-8509-5692E3431D53}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {DED76823-F195-46D4-8509-5692E3431D53}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {DED76823-F195-46D4-8509-5692E3431D53}.Release|x64.ActiveCfg = Release|Any CPU 50 | {DED76823-F195-46D4-8509-5692E3431D53}.Release|x64.Build.0 = Release|Any CPU 51 | {DED76823-F195-46D4-8509-5692E3431D53}.Release|x86.ActiveCfg = Release|Any CPU 52 | {DED76823-F195-46D4-8509-5692E3431D53}.Release|x86.Build.0 = Release|Any CPU 53 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 54 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Debug|Any CPU.Build.0 = Debug|Any CPU 55 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Debug|x64.ActiveCfg = Debug|Any CPU 56 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Debug|x64.Build.0 = Debug|Any CPU 57 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Debug|x86.ActiveCfg = Debug|Any CPU 58 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Debug|x86.Build.0 = Debug|Any CPU 59 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Release|Any CPU.ActiveCfg = Release|Any CPU 60 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Release|Any CPU.Build.0 = Release|Any CPU 61 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Release|x64.ActiveCfg = Release|Any CPU 62 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Release|x64.Build.0 = Release|Any CPU 63 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Release|x86.ActiveCfg = Release|Any CPU 64 | {024C85A1-1144-4D1A-ADCC-010845B94620}.Release|x86.Build.0 = Release|Any CPU 65 | EndGlobalSection 66 | GlobalSection(NestedProjects) = preSolution 67 | {2804EC63-670C-4970-85E4-2A63C9327FF8} = {B26D43AA-4A35-4035-9E99-48EF9A3E64DD} 68 | {DED76823-F195-46D4-8509-5692E3431D53} = {348A52EC-7046-4D1A-88DB-55B025C2BB68} 69 | {024C85A1-1144-4D1A-ADCC-010845B94620} = {B26D43AA-4A35-4035-9E99-48EF9A3E64DD} 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /code/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skills/secure-repository-supply-chain/d9dbacf8ca634ab0c6869b434ff006d7e32ccd29/code/readme.md -------------------------------------------------------------------------------- /code/src/Attendee/Attendee.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.IO.Compression; 4 | 5 | namespace Attendees 6 | { 7 | 8 | public class Attendee 9 | { 10 | public void WriteToDirectory(ZipArchiveEntry entry, string destDirectory) 11 | { 12 | string destFileName = Path.Combine(destDirectory, entry.FullName); 13 | entry.ExtractToFile(destFileName); 14 | } 15 | 16 | public bool AddAttendee(string added) 17 | { 18 | if (added == "exists") { 19 | return true; 20 | } 21 | return false; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /code/src/Attendee/Attendee.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/Attendee.js: -------------------------------------------------------------------------------- 1 | function attendeeName() { 2 | document.getElementById("Name").innerHTML = "Enter Name."; 3 | } 4 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/AttendeeSite.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace AttendeeSite.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace AttendeeSite 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:25666", 8 | "sslPort": 44370 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "AttendeeSite": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "swagger", 25 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | using Microsoft.OpenApi.Models; 14 | 15 | namespace AttendeeSite 16 | { 17 | public class Startup 18 | { 19 | public Startup(IConfiguration configuration) 20 | { 21 | Configuration = configuration; 22 | } 23 | 24 | public IConfiguration Configuration { get; } 25 | 26 | // This method gets called by the runtime. Use this method to add services to the container. 27 | public void ConfigureServices(IServiceCollection services) 28 | { 29 | 30 | services.AddControllers(); 31 | services.AddSwaggerGen(c => 32 | { 33 | c.SwaggerDoc("v1", new OpenApiInfo { Title = "AttendeeSite", Version = "v1" }); 34 | }); 35 | } 36 | 37 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 38 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 39 | { 40 | if (env.IsDevelopment()) 41 | { 42 | app.UseDeveloperExceptionPage(); 43 | app.UseSwagger(); 44 | app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "AttendeeSite v1")); 45 | } 46 | 47 | app.UseHttpsRedirection(); 48 | 49 | app.UseRouting(); 50 | 51 | app.UseAuthorization(); 52 | 53 | app.UseEndpoints(endpoints => 54 | { 55 | endpoints.MapControllers(); 56 | }); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AttendeeSite 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.1.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "axios": { 8 | "version": "0.21.1", 9 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 10 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 11 | "requires": { 12 | "follow-redirects": "^1.10.0", 13 | "minimist": "^1.2.0" 14 | } 15 | }, 16 | "json5": { 17 | "version": "2.2.0", 18 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 19 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 20 | "requires": { 21 | "minimist": "^1.2.5" 22 | } 23 | }, 24 | "minimist": { 25 | "version": "1.2.5", 26 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 27 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code/src/AttendeeSite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "azure_provision", 3 | "version": "1.0.0", 4 | "description": "provision to azure cloud", 5 | "main": "provisionComposer.js", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "node provisionComposer.js" 9 | }, 10 | "dependencies": { 11 | "@azure/arm-appinsights": "^2.1.0", 12 | "@azure/arm-botservice": "^1.0.0", 13 | "@azure/arm-resources": "^2.1.0", 14 | "@azure/graph": "^5.0.1", 15 | "@azure/ms-rest-nodeauth": "^3.0.3", 16 | "@types/fs-extra": "^8.1.0", 17 | "axios": "^0.21.1", 18 | "chalk": "^4.0.0", 19 | "fs-extra": "^8.1.0", 20 | "minimist": "^1.2.5", 21 | "ora": "^4.0.4", 22 | "request-promise": "^4.2.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /code/test/AttendeeTest/AttendeeExists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using Xunit.Extensions; 4 | using Attendees; 5 | 6 | namespace AttendeeTest 7 | { 8 | public class AttendeeTest 9 | { 10 | [Fact] 11 | public void AttendeeExistsReturnTrue() 12 | { 13 | Attendee attendee = new Attendee(); 14 | bool doesExist = attendee.AddAttendee("doesnotexist"); 15 | Assert.False(doesExist, "The attendee does not exist"); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /code/test/AttendeeTest/AttendeeTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | all 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | --------------------------------------------------------------------------------