mitid-connect 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. mitid_connect-0.0.1/.git_archival.txt +3 -0
  2. mitid_connect-0.0.1/.gitattributes +2 -0
  3. mitid_connect-0.0.1/.github/dependabot.yml +24 -0
  4. mitid_connect-0.0.1/.github/release.yml +25 -0
  5. mitid_connect-0.0.1/.github/rulesets/branch-names.json +26 -0
  6. mitid_connect-0.0.1/.github/rulesets/main.json +63 -0
  7. mitid_connect-0.0.1/.github/workflows/close-inactive-issues.yml +30 -0
  8. mitid_connect-0.0.1/.github/workflows/library-released.yml +32 -0
  9. mitid_connect-0.0.1/.github/workflows/release-drafter.yml +28 -0
  10. mitid_connect-0.0.1/.github/workflows/release.yml +91 -0
  11. mitid_connect-0.0.1/.github/workflows/tests.yml +42 -0
  12. mitid_connect-0.0.1/.gitignore +12 -0
  13. mitid_connect-0.0.1/CLAUDE.md +147 -0
  14. mitid_connect-0.0.1/LICENSE +22 -0
  15. mitid_connect-0.0.1/PKG-INFO +55 -0
  16. mitid_connect-0.0.1/README.md +24 -0
  17. mitid_connect-0.0.1/pyproject.toml +76 -0
  18. mitid_connect-0.0.1/requirements-test.txt +11 -0
  19. mitid_connect-0.0.1/setup.cfg +4 -0
  20. mitid_connect-0.0.1/src/mitid_connect/__init__.py +29 -0
  21. mitid_connect-0.0.1/src/mitid_connect/browser_client.py +813 -0
  22. mitid_connect-0.0.1/src/mitid_connect/helpers.py +98 -0
  23. mitid_connect-0.0.1/src/mitid_connect/py.typed +0 -0
  24. mitid_connect-0.0.1/src/mitid_connect/srp.py +216 -0
  25. mitid_connect-0.0.1/src/mitid_connect.egg-info/PKG-INFO +55 -0
  26. mitid_connect-0.0.1/src/mitid_connect.egg-info/SOURCES.txt +31 -0
  27. mitid_connect-0.0.1/src/mitid_connect.egg-info/dependency_links.txt +1 -0
  28. mitid_connect-0.0.1/src/mitid_connect.egg-info/requires.txt +5 -0
  29. mitid_connect-0.0.1/src/mitid_connect.egg-info/scm_file_list.json +28 -0
  30. mitid_connect-0.0.1/src/mitid_connect.egg-info/scm_version.json +8 -0
  31. mitid_connect-0.0.1/src/mitid_connect.egg-info/top_level.txt +1 -0
  32. mitid_connect-0.0.1/tests/test_helpers.py +13 -0
  33. mitid_connect-0.0.1/tests/test_srp.py +47 -0
@@ -0,0 +1,3 @@
1
+ node: $Format:%H$
2
+ node-date: $Format:%cI$
3
+ describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$
@@ -0,0 +1,2 @@
1
+ # GitHub's source downloads carry the version setuptools-scm needs, from this file.
2
+ .git_archival.txt export-subst
@@ -0,0 +1,24 @@
1
+ # Proposes updates to the pinned actions and test tools as pull requests, which the tests then
2
+ # check before anything is merged.
3
+ #
4
+ # Shared by every library of the owner, from HairingX/workflows; this file is a copy of its
5
+ # template and is checked to stay so.
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: github-actions
9
+ directory: /
10
+ schedule:
11
+ interval: weekly
12
+ labels:
13
+ - dependencies
14
+ assignees:
15
+ - HairingX
16
+
17
+ - package-ecosystem: pip
18
+ directory: /
19
+ schedule:
20
+ interval: weekly
21
+ labels:
22
+ - dependencies
23
+ assignees:
24
+ - HairingX
@@ -0,0 +1,25 @@
1
+ # How GitHub groups a release's notes: each pull request by its labels.
2
+ changelog:
3
+ # The notes are for users: what is changed for them, not work on the repository itself.
4
+ exclude:
5
+ labels:
6
+ - skip-changelog
7
+ - chore
8
+ - documentation
9
+ - dependencies
10
+ categories:
11
+ - title: 🛠 Breaking Changes
12
+ labels:
13
+ - breaking-change
14
+ - title: 🚀 Features
15
+ labels:
16
+ - feature request
17
+ - enhancement
18
+ - title: 🐛 Bug Fixes
19
+ labels:
20
+ - bug
21
+ - fix
22
+ - bugfix
23
+ - title: Other Changes
24
+ labels:
25
+ - "*"
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "Branch names",
3
+ "target": "branch",
4
+ "enforcement": "active",
5
+ "conditions": {
6
+ "ref_name": {
7
+ "include": [
8
+ "~ALL"
9
+ ],
10
+ "exclude": [
11
+ "refs/heads/main",
12
+ "refs/heads/feature/**/*",
13
+ "refs/heads/fix/**/*",
14
+ "refs/heads/docs/**/*",
15
+ "refs/heads/chore/**/*",
16
+ "refs/heads/dependabot/**/*"
17
+ ]
18
+ }
19
+ },
20
+ "bypass_actors": [],
21
+ "rules": [
22
+ {
23
+ "type": "creation"
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "main: pull requests only",
3
+ "target": "branch",
4
+ "enforcement": "active",
5
+ "conditions": {
6
+ "ref_name": {
7
+ "include": [
8
+ "~DEFAULT_BRANCH"
9
+ ],
10
+ "exclude": []
11
+ }
12
+ },
13
+ "bypass_actors": [
14
+ {
15
+ "actor_id": 5,
16
+ "actor_type": "RepositoryRole",
17
+ "bypass_mode": "pull_request"
18
+ }
19
+ ],
20
+ "rules": [
21
+ {
22
+ "type": "deletion"
23
+ },
24
+ {
25
+ "type": "non_fast_forward"
26
+ },
27
+ {
28
+ "type": "pull_request",
29
+ "parameters": {
30
+ "required_approving_review_count": 0,
31
+ "dismiss_stale_reviews_on_push": false,
32
+ "require_code_owner_review": false,
33
+ "require_last_push_approval": false,
34
+ "required_review_thread_resolution": false
35
+ }
36
+ },
37
+ {
38
+ "type": "required_status_checks",
39
+ "parameters": {
40
+ "strict_required_status_checks_policy": false,
41
+ "do_not_enforce_on_create": false,
42
+ "required_status_checks": [
43
+ {
44
+ "context": "Python 3.12",
45
+ "integration_id": 15368
46
+ },
47
+ {
48
+ "context": "Python 3.13",
49
+ "integration_id": 15368
50
+ },
51
+ {
52
+ "context": "Python 3.14",
53
+ "integration_id": 15368
54
+ },
55
+ {
56
+ "context": "Libraries released and pinned",
57
+ "integration_id": 15368
58
+ }
59
+ ]
60
+ }
61
+ }
62
+ ]
63
+ }
@@ -0,0 +1,30 @@
1
+ name: Close inactive issues
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ schedule:
6
+ - cron: "30 1 * * *"
7
+
8
+ permissions: {}
9
+
10
+ # The shell given explicitly, so GitHub runs every step with pipefail.
11
+ defaults:
12
+ run:
13
+ shell: bash
14
+
15
+ jobs:
16
+ close-issues:
17
+ runs-on: ubuntu-latest
18
+ permissions:
19
+ issues: write
20
+ pull-requests: write
21
+ steps:
22
+ - uses: actions/stale@v11
23
+ with:
24
+ days-before-issue-stale: 30
25
+ days-before-issue-close: 14
26
+ stale-issue-label: "stale"
27
+ stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
28
+ close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
29
+ days-before-pr-stale: -1
30
+ days-before-pr-close: -1
@@ -0,0 +1,32 @@
1
+ name: Library released
2
+
3
+ # A pull request is merged only once every library developed alongside the package comes from
4
+ # its release, not from a branch of the pull request's name.
5
+ #
6
+ # The workflows and the tools are shared by every library of the owner, from
7
+ # HairingX/workflows; this file is a copy of its template and is checked to stay so.
8
+ on:
9
+ pull_request:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ # The shell given explicitly, so GitHub runs every step with pipefail.
15
+ defaults:
16
+ run:
17
+ shell: bash
18
+
19
+ jobs:
20
+ released:
21
+ name: Libraries released and pinned
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Check out repository
25
+ uses: actions/checkout@v7
26
+ with:
27
+ persist-credentials: false
28
+
29
+ - name: No library from a branch
30
+ uses: HairingX/workflows/python/actions/libraries-released@v2
31
+ with:
32
+ branch: ${{ github.head_ref }}
@@ -0,0 +1,28 @@
1
+ name: Release Drafter
2
+
3
+ # Keeps a draft release proposing the next version, and labels pull requests by their branch's
4
+ # name. The draft is never published by hand: the Release workflow publishes it.
5
+ #
6
+ # The workflows and the tools are shared by every repository of the owner, from
7
+ # HairingX/workflows; this file is a copy of its template and is checked to stay so.
8
+ on:
9
+ push:
10
+ branches:
11
+ - main
12
+ pull_request:
13
+ types: [opened, reopened, synchronize]
14
+
15
+ permissions: {}
16
+
17
+ # The shell given explicitly, so GitHub runs every step with pipefail.
18
+ defaults:
19
+ run:
20
+ shell: bash
21
+
22
+ jobs:
23
+ drafter:
24
+ name: Release Drafter
25
+ permissions:
26
+ contents: write
27
+ pull-requests: write
28
+ uses: HairingX/workflows/.github/workflows/release-drafter.yml@v2
@@ -0,0 +1,91 @@
1
+ name: Release
2
+
3
+ # Run this from the Actions tab, on main, once the maintainer has approved the draft release and
4
+ # its version. Never publish the draft release by hand: the package takes its version from the
5
+ # tag, and only this workflow tags a tested commit.
6
+ #
7
+ # The file name matters: PyPI trusted publishing is bound to this repository, this workflow file
8
+ # and the pypi environment, and takes no reusable workflow, so the upload runs here.
9
+ #
10
+ # The workflows and the tools are shared by every library of the owner, from
11
+ # HairingX/workflows; this file is a copy of its template and is checked to stay so.
12
+ on:
13
+ workflow_dispatch:
14
+ inputs:
15
+ release:
16
+ description: >-
17
+ What to release. The version is worked out from the tags, PyPI and the draft release:
18
+ the next release candidate, or the final release that ends the series.
19
+ required: true
20
+ type: choice
21
+ options:
22
+ - release candidate
23
+ - final release
24
+ default: release candidate
25
+ version:
26
+ description: >-
27
+ Override, only for a new major version, which is never worked out, or when the version
28
+ worked out is wrong: canonical PEP 440 without a v, such as 1.0.0 or 1.0.0rc1, of the
29
+ kind chosen above. It must still be higher than every version tagged or on PyPI.
30
+ required: false
31
+ type: string
32
+
33
+ permissions: {}
34
+
35
+ # GitHub keeps one waiting run per group: a third dispatch cancels the one waiting.
36
+ concurrency:
37
+ group: release
38
+ cancel-in-progress: false
39
+
40
+ # The shell given explicitly, so GitHub runs every step with pipefail.
41
+ defaults:
42
+ run:
43
+ shell: bash
44
+
45
+ jobs:
46
+ release:
47
+ name: Release
48
+ permissions:
49
+ contents: write
50
+ pull-requests: read
51
+ actions: read
52
+ uses: HairingX/workflows/.github/workflows/python-release.yml@v2
53
+ with:
54
+ release: ${{ inputs.release }}
55
+ version: ${{ inputs.version }}
56
+
57
+ pypi:
58
+ name: Publish to PyPI
59
+ needs: release
60
+ runs-on: ubuntu-latest
61
+ permissions:
62
+ # Mandatory for trusted publishing.
63
+ id-token: write
64
+ environment:
65
+ name: pypi
66
+ url: https://pypi.org/p/${{ needs.release.outputs.package }}
67
+ steps:
68
+ - name: Fetch the distributions
69
+ uses: actions/download-artifact@v8
70
+ with:
71
+ name: dist
72
+ path: dist/
73
+
74
+ # A re-run finds the version it uploaded before.
75
+ - name: Publish
76
+ uses: pypa/gh-action-pypi-publish@release/v1
77
+ with:
78
+ skip-existing: true
79
+
80
+ github-release:
81
+ name: GitHub release
82
+ needs: [release, pypi]
83
+ permissions:
84
+ contents: write
85
+ uses: HairingX/workflows/.github/workflows/python-github-release.yml@v2
86
+ with:
87
+ tag: ${{ needs.release.outputs.tag }}
88
+ prerelease: ${{ needs.release.outputs.prerelease }}
89
+ previous_tag: ${{ needs.release.outputs.previous_tag }}
90
+ draft_id: ${{ needs.release.outputs.draft_id }}
91
+ draft_body: ${{ needs.release.outputs.draft_body }}
@@ -0,0 +1,42 @@
1
+ name: Tests
2
+
3
+ # The workflows and the tools are shared by every library of the owner, from
4
+ # HairingX/workflows; this file is a copy of its template and is checked to stay so.
5
+ on:
6
+ push:
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ concurrency:
14
+ group: tests-${{ github.event_name }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ # The shell given explicitly, so GitHub runs every step with pipefail.
18
+ defaults:
19
+ run:
20
+ shell: bash
21
+
22
+ jobs:
23
+ test:
24
+ name: Python ${{ matrix.python-version }}
25
+ runs-on: ubuntu-latest
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ python-version: ["3.12", "3.13", "3.14"]
30
+ steps:
31
+ - name: Check out repository, with every tag
32
+ uses: actions/checkout@v7
33
+ with:
34
+ persist-credentials: false
35
+ # setuptools-scm works the package's version out from the tags.
36
+ fetch-depth: 0
37
+
38
+ - name: Tests and type check
39
+ uses: HairingX/workflows/python/actions/tests@v2
40
+ with:
41
+ python-version: ${{ matrix.python-version }}
42
+ branch: ${{ github.head_ref || github.ref_name }}
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ build/
4
+ dist/
5
+ .venv/
6
+ .pytest_cache/
7
+ .coverage
8
+ .idea/
9
+ .DS_Store
10
+ .claude/worktrees/
11
+ mysecrets.py
12
+
@@ -0,0 +1,147 @@
1
+ # Conventions for this repository
2
+
3
+ A Python library that logs in through MitID: an unofficial implementation of MitID's browser
4
+ client, which authenticates with the MitID app (QR code or one-time code) or a code token and
5
+ gives back the authorization code the service being logged in to exchanges for its own tokens.
6
+ It knows nothing of any one service; `aula_connect` is one that uses it.
7
+
8
+ ## This library
9
+
10
+ - A MitID username, password, code and every token are credentials: never logged, never in a
11
+ tracked file. A live test takes them from environment variables and skips without them.
12
+ - It talks only to MitID (`www.mitid.dk`) and, for choosing between identities, to the
13
+ NemLog-in page the service's flow is on.
14
+ - The code is MIT-licensed. It carries on Hundter's MitID-BrowserClient, whose copyright stays
15
+ in `LICENSE`.
16
+
17
+ <!-- BEGIN HairingX/workflows: shared; edit it there -->
18
+ ## Shared by every library
19
+
20
+ This section, the workflows and the release tools are the same in every Python library of the
21
+ owner. They come from `HairingX/workflows`: the workflows in `.github/` are copies of its
22
+ template, which call its reusable workflows and actions at `@v2`, and this section is a copy of
23
+ its `python/template/CLAUDE.md`. The tests check that the copies agree; a change to any of them is
24
+ made there, released, and synced into every repository with its
25
+ `common/tools/template.py sync python`. What is this repository's own is above this section.
26
+
27
+ ## Comments and docstrings
28
+
29
+ Based on PEP 8 (Comments), PEP 257 (Docstring Conventions) and the Google Python Style Guide
30
+ (3.8 Comments and Docstrings).
31
+
32
+ **Docstrings describe the unit's own contract, and nothing else.**
33
+ - Every public module, class, function and method has one.
34
+ - The first line is a one-sentence summary. Add more only when a caller needs it: arguments,
35
+ return value, exceptions raised, side effects, invariants.
36
+ - Use Google style sections (`Args:`, `Returns:`, `Raises:`) only when they say something the
37
+ signature and type hints do not. Never repeat types; the hints carry them.
38
+ - Describe what the unit does, not who calls it, how other classes use its data, or where its
39
+ result ends up. That knowledge belongs to those other units and goes stale here.
40
+
41
+ **Comments explain why, never what.**
42
+ - Write one only where the code cannot say it: a protocol quirk, a non-obvious constraint, the
43
+ reason for an order of operations.
44
+ - No history: no "used to", "previously", "the old code", "this was a bug". Version control
45
+ holds history; a regression test's name holds the reason it exists.
46
+ - No references to other files, classes, line numbers or design-document sections. They rot the
47
+ moment the other side changes.
48
+ - No commented-out code. No TODO without an issue reference.
49
+
50
+ **Keep them short.** A comment longer than a few lines is design rationale; it belongs in
51
+ `docs/`, where it can cover several modules at once.
52
+
53
+ **Tests.** The test name states the behaviour. Add a docstring only when the reason is not
54
+ obvious from the name - one or two lines, no narrative.
55
+
56
+ ## Conventions
57
+
58
+ - All documentation, comments and commit messages are in English.
59
+ - The package lives in `src/<package>/`, ships its types (`py.typed`), and supports Python 3.12
60
+ and later (`requires-python = ">=3.12"`); the tests run on 3.12, 3.13 and 3.14.
61
+ - pyright strict must report 0 errors (`pyright`); the configuration is in `pyproject.toml`.
62
+ No `# type: ignore` and no rule turned off.
63
+ - The tests are pytest, in `tests/`, and cover every line of the package; the build fails below
64
+ 100%. They import the installed package, as its users do, never `src.<package>`: a packaging
65
+ mistake then fails a test before a release. Tests that need a real device are marked `live`,
66
+ skip themselves without one, and never run in CI.
67
+ - A repository on its way to this standard says so under `[tool.hairingx-workflows]` in
68
+ `pyproject.toml`: `transition` says why, and `coverage` the percentage its tests must reach
69
+ meanwhile; pyright, still strict, may leave the files listed in `[tool.pyright] ignore`
70
+ unchecked. Every run warns while it lasts. Each pull request raises the coverage and takes
71
+ files off the list, never the reverse, until the transition is removed.
72
+ - Every problem found gets a test that fails without the fix.
73
+ - The test tools are pinned with `==` in `requirements-test.txt`, pyright, pytest and
74
+ pytest-cov among them: `pip install -e . -r requirements-test.txt`.
75
+ - No real IP addresses, hostnames, serial numbers, email addresses or credentials in tracked
76
+ files; real values live in a gitignored file or in environment variables. Examples use the
77
+ documentation ranges, such as 192.0.2.0/24. A credential is never logged.
78
+
79
+ ## Releasing
80
+
81
+ **The version is the release's tag, and the draft release is never published by hand.** The
82
+ package has no version in a file: setuptools-scm works it out from the tags when it is built, so a
83
+ checkout between releases says a development version such as `0.2.1.dev3+g1a2b3c4`.
84
+
85
+ 1. Merge pull requests into `main`. Release Drafter keeps a draft release proposing the next
86
+ version: a minor bump for the label `breaking-change` or `minor`, a patch otherwise.
87
+ **A new major version is never worked out**, as a label placed wrongly must not release one;
88
+ type it into Release as the override.
89
+ 2. Wait until the Release Drafter run on `main` has finished. Release refuses a draft that is not
90
+ up to date with `main`.
91
+ 3. Show the maintainer the draft's notes and its version, and get explicit approval before
92
+ running Release.
93
+ 4. Run the **Release** workflow from the Actions tab, on `main`, and choose **release
94
+ candidate** or **final release**. It works out the version: the next release candidate of the
95
+ open series (`0.2.0rc1` -> `0.2.0rc2`), or the final release that ends it (`0.2.0`); a draft
96
+ naming a higher version starts a new series. Type a version only for a new major, or to
97
+ override one worked out wrongly: canonical PEP 440, of the kind chosen.
98
+
99
+ Release refuses any version not higher than every version tagged or on PyPI, yanked ones
100
+ included, and a version with no pull request merged since the release before it - for a final
101
+ release, the final release before it. It runs the tests on the exact commit it releases, tags
102
+ that commit, builds, checks that the built package says the version, and only then pushes the
103
+ tag - nothing is pushed to `main`. Then PyPI, then the GitHub release with the distributions,
104
+ marked as a pre-release where it is one.
105
+
106
+ A release candidate's notes are written by GitHub from the pull requests merged since the
107
+ previous release candidate or final release, grouped by label as `.github/release.yml` says, and
108
+ the draft is kept. A final release's notes are the draft's - the first final release says only
109
+ that it is the initial release - and the final release deletes the draft. To change what a
110
+ release says, change the pull requests: the title is the line, the labels decide the section.
111
+
112
+ If publishing fails part-way, **Re-run failed jobs** resumes it: the tag, PyPI and the GitHub
113
+ release each accept what an earlier attempt already did.
114
+
115
+ PyPI trusted publishing is bound to this repository, the workflow file `release.yml` and the
116
+ `pypi` environment: renaming either breaks the upload. Actions are referred to by their major
117
+ version; Dependabot proposes a new major, and updates to the test tools, as pull requests.
118
+
119
+ ## Libraries developed together
120
+
121
+ A library this one depends on and develops alongside is listed, in install order, under
122
+ `[tool.hairingx-workflows] libraries` in `pyproject.toml`. A development branch is tested with
123
+ that library's branch of the same name, where it has one, over its release; the check
124
+ "Libraries released and pinned" then fails until the library is released, its version required
125
+ in `pyproject.toml`, and its branch deleted. **Release a library first**, then require its
126
+ version here.
127
+
128
+ ## Branches and pull requests
129
+
130
+ - Every change goes through a branch and a pull request: `main` takes no push. The ruleset in
131
+ `.github/rulesets/main.json` enforces it, with the checks "Python 3.12", "Python 3.13",
132
+ "Python 3.14" and "Libraries released and pinned" required; its only bypass is the owner's,
133
+ and only for merging a pull request. A change to what a user gets - the library's code or
134
+ documentation - comes with its tests.
135
+ - Name every branch by the kind of change, as the release draft's labels follow the name;
136
+ `.github/rulesets/branch-names.json` refuses any other name. `feature/<what>` is labelled
137
+ `feature request`, `fix/<what>` is labelled `bug`, `docs/<what>` is labelled `documentation`,
138
+ and `chore/<what>` - CI, tooling, anything that stays in the repository - is labelled `chore`.
139
+ The release notes list features and fixes; documentation, chores and Dependabot's
140
+ `dependencies` are left out. A change to what a user installs, such as a new dependency, is a
141
+ `fix/` or a `feature/`, never a `chore/`.
142
+ - A pull request's text describes only its own change: what it does and how it was tested. Never
143
+ releases to come, merge order, or other repositories.
144
+ - Put `breaking-change` on a pull request that breaks the API - a `feature/` or `fix/` one, as a
145
+ chore is left out of the notes - and `minor` on one that needs a minor bump; both give a minor
146
+ bump, and a patch is the default. No label gives a major.
147
+ <!-- END HairingX/workflows -->
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) Hundter, the author of MitID-BrowserClient, which this library carries on
4
+ Copyright (c) 2026 HairingX
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.4
2
+ Name: mitid_connect
3
+ Version: 0.0.1
4
+ Summary: Log in through MitID from Python: an unofficial implementation of MitID's browser client, with the MitID app or a code token.
5
+ Author: HairingX
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/HairingX/mitid_connect
8
+ Project-URL: Source, https://github.com/HairingX/mitid_connect
9
+ Project-URL: Issues, https://github.com/HairingX/mitid_connect/issues
10
+ Project-URL: Releases, https://github.com/HairingX/mitid_connect/releases
11
+ Keywords: mitid,nemlog-in,login,denmark
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.12
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: beautifulsoup4>=4.12.0
26
+ Requires-Dist: lxml>=5.0.0
27
+ Requires-Dist: pycryptodomex>=3.24.1
28
+ Requires-Dist: qrcode>=8.2
29
+ Requires-Dist: requests>=2.31.0
30
+ Dynamic: license-file
31
+
32
+ # mitid_connect
33
+
34
+ Log in through [MitID](https://www.mitid.dk) from Python: an unofficial implementation of MitID's
35
+ browser client. It authenticates with the MitID app - by QR code or one-time code - or with a
36
+ code token, and gives back the authorization code that the service being logged in to exchanges
37
+ for its own tokens.
38
+
39
+ ```python
40
+ from mitid_connect import BrowserClient
41
+
42
+ client = BrowserClient(client_hash, authentication_session_id)
43
+ authenticators = client.identify_as_user_and_get_available_authenticators("username")
44
+ client.authenticate_with_app() # approve in the MitID app
45
+ code = client.finalize_authentication_and_get_authorization_code()
46
+ ```
47
+
48
+ `client_hash` and `authentication_session_id` come from the service's NemLog-in page;
49
+ `get_authentication_code` does all of the above from that page's parameters.
50
+
51
+ It is used by [aula_connect](https://github.com/HairingX/aula_connect) to log in to Aula.
52
+
53
+ ## Origin and licence
54
+
55
+ It carries on MitID-BrowserClient by Hundter, under the MIT licence (`LICENSE`).
@@ -0,0 +1,24 @@
1
+ # mitid_connect
2
+
3
+ Log in through [MitID](https://www.mitid.dk) from Python: an unofficial implementation of MitID's
4
+ browser client. It authenticates with the MitID app - by QR code or one-time code - or with a
5
+ code token, and gives back the authorization code that the service being logged in to exchanges
6
+ for its own tokens.
7
+
8
+ ```python
9
+ from mitid_connect import BrowserClient
10
+
11
+ client = BrowserClient(client_hash, authentication_session_id)
12
+ authenticators = client.identify_as_user_and_get_available_authenticators("username")
13
+ client.authenticate_with_app() # approve in the MitID app
14
+ code = client.finalize_authentication_and_get_authorization_code()
15
+ ```
16
+
17
+ `client_hash` and `authentication_session_id` come from the service's NemLog-in page;
18
+ `get_authentication_code` does all of the above from that page's parameters.
19
+
20
+ It is used by [aula_connect](https://github.com/HairingX/aula_connect) to log in to Aula.
21
+
22
+ ## Origin and licence
23
+
24
+ It carries on MitID-BrowserClient by Hundter, under the MIT licence (`LICENSE`).