Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lib): Add matrix auth lib #509

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Conversation

merkata
Copy link
Contributor

@merkata merkata commented Sep 9, 2024

Overview

Adds a plugins library to manage (charmed) Matrix/Synapse plugins.

Rationale

Decoupling of plugins from the main code to standalone charms.

Juju Events Changes

n/a

Module Changes

n/a

Library Changes

Adds a matrix_auth.py for authentication mechanisms between a Matrix server and a plugin.

Checklist

@merkata merkata added the complex label Sep 9, 2024
@merkata merkata requested a review from a team as a code owner September 9, 2024 14:37
@@ -0,0 +1,516 @@
# Copyright 2024 Canonical Ltd.
# Licensed under the Apache2.0. See LICENSE file in charm source for details.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be shipped without the LICENSE file., so I'd go for

# 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
#
# http://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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting point and you made me have a look at other libs :)

So observability have a reference to a LICENSE file, while data platform do not for instance. We make a reference to a LICENSE file on the nginx route library.

~/dev/canonical
❯ head is-charms/synapse-operator/lib/charms/observability_libs/v0/juju_topology.py
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.
"""## Overview.

This document explains how to use the `JujuTopology` class to
create and consume topology information from Juju in a consistent manner.

~/dev/canonical
❯ head is-charms/synapse-operator/lib/charms/data_platform_libs/v0/data_interfaces.py
# Copyright 2023 Canonical Ltd.
#
# 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
#
# http://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,

~/dev/canonical
❯ head is-charms/synapse-operator/lib/charms/prometheus_k8s/v0/prometheus_scrape.py
# Copyright 2021 Canonical Ltd.
# See LICENSE file for licensing details.

~/dev/canonical
❯ head is-charms/synapse-operator/lib/charms/nginx_ingress_integrator/v0/nginx_route.py
# Copyright 2024 Canonical Ltd.
# Licensed under the Apache2.0. See LICENSE file in charm source for details.

I see charmcraft doesn't care, which makes sense, so maybe @erinecon and @gregory-schiano can chip in?

Personally, I'm in favor of removing this and for consistency sake do a cleanup of our libs (like mentioned, at least nginx has that). I checked and bind-operator has that same reference.

Thanks for spotting! 👓

Copy link
Collaborator

@arturo-seijas arturo-seijas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice to unit test the library

dumped_model = self.model_dump(exclude_unset=True)
dumped_data = {
"shared_secret_id": dumped_model["shared_secret_id"],
"homeserver": dumped_model["homeserver"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will be the format?
Maubot, for example, expects something like http://10.1.74.65:8080

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting point, the homeserver.yaml currently has server_name and public_baseurl - I'm saying this because I think all plugins over a plugin library will use the public interface. I'm not assuming they will share a network in any case (like a namespaced one, or an internal one etc.), and at least for the irc charm it will be a cross-model between the irc machine charm and the k8s synapse one. I would recommend the server_name and from there either the provide part prepends an "https://", or the requirer does it. I saw the public_baseurl is optional and requires a SAML integration, whereas you will always need to have a server_name set.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using server_name might be challenging in case of different URL (ubuntu.com x chat-server.ubuntu.com)

What about adding a config to set the URL that will be used for the integration? Default to server_name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point, the server name is indeed ubuntu.com and while Element clients look for a .wellknown file under the domain, plugins don't do that (looking at the irc plugin code it will not go that extra length of searching for a .wellknown file, it will connect to the name you give it). That's a great catch! I think the safe bet here is to have it as a config. I don't think we can get the DNS entry for the Synapse homeserver from Synapse, we can extract the homeserver, though clients resolve it again...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for config then :)

@merkata
Copy link
Contributor Author

merkata commented Sep 11, 2024

It'd be nice to unit test the library

Yup I think it should be done - is there anything we have in place that you can point me to, @arturo-seijas (and @amandahla )? I spoke with @jdkandersson , I wasn't sure where to put the tests (do we follow a convention, so I have a matrix_auth.py lib and have a corresponding tests/unit/test_matrix_auth.py, or maybe tests/unit/lib/test_matrix_auth.py or even tests/unit/lib/synapse/v0/test_matrix_auth.py...) and do I wanted to see what to cover in a unit test (pydantic models, mocking with Harness, testing state with Scenario), have we done something in that direction? CCing @gregory-schiano as he mentioned tests for the lib already (several times 😄 ).

@arturo-seijas
Copy link
Collaborator

It'd be nice to unit test the library

Yup I think it should be done - is there anything we have in place that you can point me to, @arturo-seijas (and @amandahla )? I spoke with @jdkandersson , I wasn't sure where to put the tests (do we follow a convention, so I have a matrix_auth.py lib and have a corresponding tests/unit/test_matrix_auth.py, or maybe tests/unit/lib/test_matrix_auth.py or even tests/unit/lib/synapse/v0/test_matrix_auth.py...) and do I wanted to see what to cover in a unit test (pydantic models, mocking with Harness, testing state with Scenario), have we done something in that direction? CCing @gregory-schiano as he mentioned tests for the lib already (several times 😄 ).

here is how I've been doing it

Copy link
Contributor

Test coverage for 65ec799

Name                                    Stmts   Miss Branch BrPart  Cover   Missing
-----------------------------------------------------------------------------------
src/actions/__init__.py                     1      0      0      0   100%
src/actions/register_user.py               21      0      2      0   100%
src/admin_access_token.py                   9      0      0      0   100%
src/backup.py                             175      5     24      2    96%   353-354, 423-424, 480->482, 483
src/backup_observer.py                    134     16     14      0    89%   132-135, 140-143, 179-182, 211-214
src/charm.py                              301     17     80      9    93%   138->140, 143, 276-277, 305, 312, 393-397, 400-401, 429-431, 451, 481-484, 507-508
src/charm_state.py                        150      8     42      6    93%   271, 275, 296, 321, 327, 333, 337-338
src/charm_types.py                         34      0     10      0   100%
src/database_client.py                     57      1     12      4    93%   35, 47->exit, 69->exit, 88->98
src/database_observer.py                   39      0      4      1    98%   70->72
src/exceptions.py                           3      0      0      0   100%
src/media_observer.py                      41      4      2      1    88%   61-63, 82
src/mjolnir.py                             97      3     34      3    95%   82, 91->107, 112-116
src/observability.py                       14      0      0      0   100%
src/pebble.py                             201     27     46     13    84%   57->62, 176->exit, 187-191, 225-226, 246-247, 300->305, 308-309, 321-322, 324-325, 339-340, 357, 359, 361, 363, 365, 393, 445-450
src/redis_observer.py                      35      3      4      0    92%   62-65
src/s3_parameters.py                       22      0      4      0   100%
src/saml_observer.py                       31      0      6      0   100%
src/smtp_observer.py                       56      4     14      2    91%   82-86, 89, 108->113
src/synapse/__init__.py                     4      0      0      0   100%
src/synapse/admin.py                       19      2      2      0    90%   40-41
src/synapse/api.py                        175      3     24      3    97%   176, 229, 402
src/synapse/workload.py                   135      2     22      0    99%   406-407
src/synapse/workload_configuration.py     163     26     46     13    81%   85->exit, 89-90, 138-139, 168, 188-189, 221-222, 255, 264-265, 286-287, 306->311, 312, 330->332, 342-343, 359, 406->409, 433-434, 462, 470->472, 472->474, 479-480, 500->507, 510, 530-531
src/user.py                                23      0      4      0   100%
-----------------------------------------------------------------------------------
TOTAL                                    1940    121    396     57    92%

Static code analysis report

Working... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
Run started:2024-09-24 13:32:41.909635

Test results:
  No issues identified.

Code scanned:
  Total lines of code: 10828
  Total lines skipped (#nosec): 4
  Total potential issues skipped due to specifically being disabled (e.g., #nosec BXXX): 0

Run metrics:
  Total issues (by severity):
  	Undefined: 0
  	Low: 0
  	Medium: 0
  	High: 0
  Total issues (by confidence):
  	Undefined: 0
  	Low: 0
  	Medium: 0
  	High: 0
Files skipped (0):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants