diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..dc599845 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,82 @@ +# 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: [ "main", "development" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '21 6 * * 3' + +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') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + # 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@v2 + 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@v2 + + # ℹī¸ 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@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 6539c0fe..d7a4a276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## [4.0.0] 2023-11-15 + +### Fixed + +Raise `OPItemEditException` when editing item fields if the item does not exist. + ## [4.0.0] 2023-11-06 ### Added diff --git a/pyonepassword/__about__.py b/pyonepassword/__about__.py index c99b0192..c866395a 100644 --- a/pyonepassword/__about__.py +++ b/pyonepassword/__about__.py @@ -1,5 +1,5 @@ __title__ = "pyonepassword" -__version__ = "4.0.0" +__version__ = "4.0.1" __summary__ = "A python API to query a 1Password account using the 'op' command-line tool" """ diff --git a/pyonepassword/pyonepassword.py b/pyonepassword/pyonepassword.py index b8946697..07be3e47 100644 --- a/pyonepassword/pyonepassword.py +++ b/pyonepassword/pyonepassword.py @@ -53,6 +53,7 @@ OPInvalidItemException, OPItemDeleteException, OPItemDeleteMultipleException, + OPItemEditException, OPItemGetException, OPItemListException, OPPasswordFieldDowngradeException, @@ -650,8 +651,6 @@ def item_edit_add_password_field(self, Raises ------ - OPItemGetException - If the item lookup fails for any reason OPFieldExistsException If the field to be added already existss OPItemEditException @@ -718,8 +717,6 @@ def item_edit_add_url_field(self, Raises ------ - OPItemGetException - If the item lookup fails for any reason OPFieldExistsException If the field to be added already existss OPItemEditException @@ -782,8 +779,6 @@ def item_edit_add_text_field(self, Raises ------ - OPItemGetException - If the item lookup fails for any reason OPFieldExistsException If the field to be added already existss OPItemEditException @@ -854,8 +849,6 @@ def item_edit_set_password(self, Raises ------ - OPItemGetException - If the item lookup fails for any reason OPSectionNotFoundException If a section label is specified but can't be looked up on the item object OPFieldNotFoundException @@ -927,8 +920,6 @@ def item_edit_set_url_field(self, Raises ------ - OPItemGetException - If the item lookup fails for any reason OPSectionNotFoundException If a section label is specified but can't be looked up on the item object OPFieldNotFoundException @@ -1001,8 +992,6 @@ def item_edit_set_text_field(self, Raises ------ - OPItemGetException - If the item lookup fails for any reason OPSectionNotFoundException If a section label is specified but can't be looked up on the item object OPFieldNotFoundException @@ -1811,8 +1800,11 @@ def _item_edit_set_field(self, # Does the item exist? # generic_okay: Enable editing of unknown OPItem types - item = self.item_get( - item_identifier, vault=vault, generic_okay=True) + try: + item = self.item_get( + item_identifier, vault=vault, generic_okay=True) + except OPItemGetException as e: + raise OPItemEditException.from_opexception(e) if not create_field: # Does the field and, if provided, the section exist? diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output index ea4743f1..e997cbb7 100644 --- a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21a/output @@ -7,7 +7,7 @@ "name": "Test Data 2" }, "category": "LOGIN", - "last_edited_by": "A47WW2CN6BEMDDS7RXRKBFQIZ4", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", "created_at": "2023-10-19T03:56:29Z", "updated_at": "2023-10-20T03:22:13Z", "additional_information": "user_22", diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output index f86d7d76..005a9bfe 100644 --- a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-21b/output @@ -7,7 +7,7 @@ "name": "Test Data 2" }, "category": "LOGIN", - "last_edited_by": "A47WW2CN6BEMDDS7RXRKBFQIZ4", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", "created_at": "2023-10-20T04:07:03Z", "updated_at": "2023-10-20T04:08:07Z", "additional_information": "user_21", diff --git a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output index aef045f6..6e3cfbac 100644 --- a/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output +++ b/tests/config/mock-op/responses-item-edit/responses-2/item-get-example-login-23/output @@ -7,7 +7,7 @@ "name": "Test Data 2" }, "category": "LOGIN", - "last_edited_by": "A47WW2CN6BEMDDS7RXRKBFQIZ4", + "last_edited_by": "FZTDCNIJAOEBZZ2VQFNDVHC3K6", "created_at": "2023-10-19T03:56:29Z", "updated_at": "2023-10-31T03:19:11Z", "additional_information": "user_23", diff --git a/tests/test_item_edit/test_item_edit_errors.py b/tests/test_item_edit/test_item_edit_errors.py index 71a8791f..a3dcd291 100644 --- a/tests/test_item_edit/test_item_edit_errors.py +++ b/tests/test_item_edit/test_item_edit_errors.py @@ -6,6 +6,7 @@ from pyonepassword.api.exceptions import ( OPFieldNotFoundException, + OPItemEditException, OPSectionNotFoundException ) from pyonepassword.py_op_exceptions import ( @@ -284,3 +285,21 @@ def test_item_edit_add_password_no_insecure_acknowledge_090(signed_in_op: OP): field_label=field_label, section_label=section_label, vault=vault) + + +def test_item_edit_invalid_item_01(signed_in_op: OP): + """ + Test: OP.item_edit_set_text_field() raises OPItemEditException appropriately + - Attempt to call item_edit_set_text_field() on an item that doesn't exist + Verify: + - OPItemEditException is raised + """ + item_name = "Invalid Item" + text_field_label = "this text field doesn't exist because the item doesn't exist" + section_label = "seriously same thing applies" + text_field_value = "whatever this isn't going to work anyway" + with pytest.raises(OPItemEditException): + signed_in_op.item_edit_set_text_field(item_name, + text_field_value, + text_field_label, + section_label=section_label)