diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..b2db6d0 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: jimmyeao +patreon: deviousweb diff --git a/.github/workflows/checkmarx-one.yml b/.github/workflows/checkmarx-one.yml new file mode 100644 index 0000000..0d4a258 --- /dev/null +++ b/.github/workflows/checkmarx-one.yml @@ -0,0 +1,55 @@ +# 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. + +# The Checkmarx One GitHub Action enables you to trigger SAST, SCA, and KICS scans directly from the GitHub workflow. +# It provides a wrapper around the Checkmarx One CLI Tool which creates a zip archive from your source code repository +# and uploads it to Checkmarx One for scanning. The Github Action provides easy integration with GitHub while enabling +# scan customization using the full functionality and flexibility of the CLI tool. + +# This is a basic workflow to help you get started with Using Checkmarx One Action, +# documentation can be found here : https://checkmarx.com/resource/documents/en/34965-68702-checkmarx-one-github-actions.html + +name: Checkmarx Scan + +# Controls when the workflow will run +on: + pull_request: + types: [opened, reopened, synchronize] + branches: [ "master" ] + +permissions: + contents: read + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif + + # The type of runner that the job will run on + runs-on: windows-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # This step checks out a copy of your repository. + - name: Checkout repository + uses: actions/checkout@v3 + # This step creates the Checkmarx One scan + - name: Checkmarx One scan + uses: checkmarx/ast-github-action@8e887bb93dacc44e0f5b64ee2b06d5815f89d4fc + with: + base_uri: https://ast.checkmarx.net # This should be replaced by your base uri for Checkmarx One + cx_client_id: ${{ secrets.CX_CLIENT_ID }} # This should be created within your Checkmarx One account : https://checkmarx.com/resource/documents/en/34965-118315-authentication-for-checkmarx-one-cli.html#UUID-a4e31a96-1f36-6293-e95a-97b4b9189060_UUID-4123a2ff-32d0-2287-8dd2-3c36947f675e + cx_client_secret: ${{ secrets.CX_CLIENT_SECRET }} # This should be created within your Checkmarx One account : https://checkmarx.com/resource/documents/en/34965-118315-authentication-for-checkmarx-one-cli.html#UUID-a4e31a96-1f36-6293-e95a-97b4b9189060_UUID-4123a2ff-32d0-2287-8dd2-3c36947f675e + cx_tenant: ${{ secrets.CX_TENANT }} # This should be replaced by your tenant for Checkmarx One + additional_params: --report-format sarif --output-path . + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v2 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: cx_result.sarif diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..06a3d72 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,81 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: '45 3 * * 6' + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'windows-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'csharp' ] + # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] + # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..3da1b17 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,27 @@ +# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '40 13 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v5 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'Stale issue message' + stale-pr-message: 'Stale pull request message' + stale-issue-label: 'no-issue-activity' + stale-pr-label: 'no-pr-activity' diff --git a/.gitignore b/.gitignore index 9491a2f..faccde0 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,8 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd + +# Visual Studio Code +.vscode/ +nuget.config diff --git a/API/MqttClientWrapper.cs b/API/MqttClientWrapper.cs index cfcd944..87107b4 100644 --- a/API/MqttClientWrapper.cs +++ b/API/MqttClientWrapper.cs @@ -27,14 +27,16 @@ public bool IsAttemptingConnection get { return _isAttemptingConnection; } private set { _isAttemptingConnection = value; } } - public MqttClientWrapper(string clientId, string mqttBroker, string username, string password) + public MqttClientWrapper(string clientId, string mqttBroker, string mqttPort, string username, string password) { var factory = new MqttFactory(); _mqttClient = factory.CreateMqttClient() as MqttClient; + int mqttportInt = System.Convert.ToInt32(mqttPort); + _mqttOptions = new MqttClientOptionsBuilder() .WithClientId(clientId) - .WithTcpServer(mqttBroker) + .WithTcpServer(mqttBroker, mqttportInt) .WithCredentials(username, password) .WithCleanSession() .Build(); diff --git a/MainWindow.xaml b/MainWindow.xaml index 2c25d20..07b8d75 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -58,6 +58,8 @@ + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index c30a675..8a42165 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -17,6 +17,7 @@ using System.Windows; using TEAMS2HA.API; +using TEAMS2HA.Properties; namespace TEAMS2HA { @@ -89,6 +90,8 @@ public static AppSettings Instance public string MqttAddress { get; set; } + public string MqttPort { get; set; } + public string MqttUsername { get; set; } public bool RunAtWindowsBoot { get; set; } @@ -256,6 +259,7 @@ public MainWindow() mqttClientWrapper = new MqttClientWrapper( "TEAMS2HA", _settings.MqttAddress, + _settings.MqttPort, _settings.MqttUsername, _settings.MqttPassword ); @@ -776,6 +780,7 @@ private async void MainPage_Loaded(object sender, RoutedEventArgs e) MqttUserNameBox.Text = _settings.MqttUsername; MQTTPasswordBox.Password = _settings.MqttPassword; MqttAddress.Text = _settings.MqttAddress; + MqttPort.Text = _settings.MqttPort; if (_settings.PlainTeamsToken == null) { TeamsApiKeyBox.Text = "Not Paired"; @@ -924,11 +929,13 @@ private bool SaveSettings() bool mqttSettingsChanged = settings.MqttAddress != MqttAddress.Text || settings.MqttUsername != MqttUserNameBox.Text || + settings.MqttPort != MqttPort.Text || settings.MqttPassword != MQTTPasswordBox.Password; settings.RunAtWindowsBoot = RunAtWindowsBootCheckBox.IsChecked ?? false; settings.RunMinimized = RunMinimisedCheckBox.IsChecked ?? false; settings.MqttAddress = MqttAddress.Text; + settings.MqttPort = MqttPort.Text; settings.MqttUsername = MqttUserNameBox.Text; settings.MqttPassword = MQTTPasswordBox.Password; settings.Theme = isDarkTheme ? "Dark" : "Light"; @@ -949,6 +956,7 @@ private void SaveSettings_Click(object sender, RoutedEventArgs e) mqttClientWrapper = new MqttClientWrapper( "TEAMS2HA", _settings.MqttAddress, + _settings.MqttPort, _settings.MqttUsername, _settings.MqttPassword ); @@ -1094,5 +1102,6 @@ private void ToggleThemeButton_Click(object sender, RoutedEventArgs e) } #endregion Private Methods + } } \ No newline at end of file diff --git a/README.md b/README.md index e6f1e10..d4a57a5 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,38 @@ -#Teams2HA +[![CodeQL](https://github.com/jimmyeao/TEAMS2HA/actions/workflows/codeql.yml/badge.svg)](https://github.com/jimmyeao/TEAMS2HA/actions/workflows/codeql.yml)[![GitHub tag](https://img.shields.io/github/tag/jimmyeao/TEAMS2HA?include_prereleases=&sort=semver&color=blue)](https://github.com/jimmyeao/TEAMS2HA/releases/) +[![License](https://img.shields.io/badge/License-MIT-blue)](#license) +[![issues - HA-Game-SPy](https://img.shields.io/github/issues/jimmyeao/TEAMS2HA)](https://github.com/jimmyeao/TEAMS2HA/issues) -This is an agent that runs on windows and uses the Local teams API (https://support.microsoft.com/en-gb/office/connect-to-third-party-devices-in-microsoft-teams-aabca9f2-47bb-407f-9f9b-81a104a883d6?wt.mc_id=SEC-MVP-5004985) to retrieve the status of the user (In a meeting, Video On, Mute, blur etc) and push these into homeassistant sensors. +

Teams2HA

-Download from https://github.com/jimmyeao/TEAMS2HA/releases +This is an agent that runs on windows and uses the Local teams API (https://support.microsoft.com/en-gb/office/connect-to-third-party-devices-in-microsoft-teams-aabca9f2-47bb-407f-9f9b-81a104a883d6?wt.mc_id=SEC-MVP-5004985) to retrieve the status of the user (In a meeting, Video On, Mute, blur etc) and push these into homeassistant sensors using MQTT. -![image](https://github.com/jimmyeao/TEAMS2HA/assets/5197831/8b98c494-a3c0-41f7-8f9b-4716037910cc) +Download the latest version from https://github.com/jimmyeao/TEAMS2HA/releases (app will auto update once installed) -You will need a long-lived token for HomeAssistant, and the URL for your instance. The Teams API key will be automagically filled when you "pair" with teams. +![image](https://github.com/jimmyeao/TEAMS2HA/assets/5197831/f8a90d5c-25be-4b00-98a8-9521827ca0b9) -Pairing +

Pairing

-to pair, have the app running, launch a teams meeting (using meetnow?) and click test teams connection. This will initiate a pairing request in teams, accept this, and then the app will store the key. +to pair, have the app running, launch a teams meeting (using meetnow?) and click Pair wtih teams. This will initiate a pairing request in teams, accept this, and then the app will store the key, in an encrypted format. The application will minimize to the system stray. -feedback is welcome, this is an early beta, but works ok for me :) +

MQTT

+ +Provide your MQTT instance details (IP, username and password) The password is encrypted before being saved to the settings file and is not stored in clear text. + +

Entities

+Click the Entities button to see a list of entities this program will create: + +![image](https://github.com/jimmyeao/TEAMS2HA/assets/5197831/a39632e7-f61c-4c0c-a953-555da53b3e0d) + +You can either right click and copy or double click to copy the entity name to the clipboard. + +

System Tray

+You can right click the system tray icon for a selection of functions: + +![image](https://github.com/jimmyeao/TEAMS2HA/assets/5197831/a8878f2e-38f6-4fce-a823-32f2008a0763) + + -sensors in Home Assistant are all prefixed with "hats." -![image](https://github.com/jimmyeao/TEAMS2HA/assets/5197831/0bec90ee-8761-4308-bbc8-2001d170078a)