Skip to content

Commit 875f09e

Browse files
authored
Merge pull request #473 from Iamrodos/chore/remove-password-auth
chore: remove deprecated -u/-p password authentication options
2 parents c70cc43 + db36c3c commit 875f09e

File tree

9 files changed

+47
-88
lines changed

9 files changed

+47
-88
lines changed

README.rst

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,51 +36,52 @@ Show the CLI help output::
3636

3737
CLI Help output::
3838

39-
github-backup [-h] [-u USERNAME] [-p PASSWORD] [-t TOKEN_CLASSIC]
40-
[-f TOKEN_FINE] [--as-app] [-o OUTPUT_DIRECTORY]
41-
[-l LOG_LEVEL] [-i] [--starred] [--all-starred]
42-
[--watched] [--followers] [--following] [--all] [--issues]
43-
[--issue-comments] [--issue-events] [--pulls]
39+
github-backup [-h] [-t TOKEN_CLASSIC] [-f TOKEN_FINE] [-q] [--as-app]
40+
[-o OUTPUT_DIRECTORY] [-l LOG_LEVEL] [-i]
41+
[--incremental-by-files]
42+
[--starred] [--all-starred]
43+
[--watched] [--followers] [--following] [--all]
44+
[--issues] [--issue-comments] [--issue-events] [--pulls]
4445
[--pull-comments] [--pull-commits] [--pull-details]
4546
[--labels] [--hooks] [--milestones] [--repositories]
46-
[--bare] [--lfs] [--wikis] [--gists] [--starred-gists]
47-
[--skip-archived] [--skip-existing] [-L [LANGUAGES ...]]
48-
[-N NAME_REGEX] [-H GITHUB_HOST] [-O] [-R REPOSITORY]
49-
[-P] [-F] [--prefer-ssh] [-v]
47+
[--bare] [--no-prune] [--lfs] [--wikis] [--gists]
48+
[--starred-gists] [--skip-archived] [--skip-existing]
49+
[-L [LANGUAGES ...]] [-N NAME_REGEX] [-H GITHUB_HOST]
50+
[-O] [-R REPOSITORY] [-P] [-F] [--prefer-ssh] [-v]
5051
[--keychain-name OSX_KEYCHAIN_ITEM_NAME]
5152
[--keychain-account OSX_KEYCHAIN_ITEM_ACCOUNT]
5253
[--releases] [--latest-releases NUMBER_OF_LATEST_RELEASES]
53-
[--skip-prerelease] [--assets] [--skip-assets-on [REPO ...]]
54-
[--attachments] [--exclude [REPOSITORY [REPOSITORY ...]]
55-
[--throttle-limit THROTTLE_LIMIT] [--throttle-pause THROTTLE_PAUSE]
54+
[--skip-prerelease] [--assets]
55+
[--skip-assets-on [SKIP_ASSETS_ON ...]] [--attachments]
56+
[--throttle-limit THROTTLE_LIMIT]
57+
[--throttle-pause THROTTLE_PAUSE]
58+
[--exclude [EXCLUDE ...]]
5659
USER
5760

5861
Backup a github account
5962

6063
positional arguments:
6164
USER github username
6265

63-
optional arguments:
66+
options:
6467
-h, --help show this help message and exit
65-
-u USERNAME, --username USERNAME
66-
username for basic auth
67-
-p PASSWORD, --password PASSWORD
68-
password for basic auth. If a username is given but
69-
not a password, the password will be prompted for.
70-
-f TOKEN_FINE, --token-fine TOKEN_FINE
71-
fine-grained personal access token or path to token
72-
(file://...)
73-
-t TOKEN_CLASSIC, --token TOKEN_CLASSIC
68+
-t, --token TOKEN_CLASSIC
7469
personal access, OAuth, or JSON Web token, or path to
7570
token (file://...)
71+
-f, --token-fine TOKEN_FINE
72+
fine-grained personal access token (github_pat_....),
73+
or path to token (file://...)
74+
-q, --quiet supress log messages less severe than warning, e.g.
75+
info
7676
--as-app authenticate as github app instead of as a user.
77-
-o OUTPUT_DIRECTORY, --output-directory OUTPUT_DIRECTORY
77+
-o, --output-directory OUTPUT_DIRECTORY
7878
directory at which to backup the repositories
79-
-l LOG_LEVEL, --log-level LOG_LEVEL
79+
-l, --log-level LOG_LEVEL
8080
log level to use (default: info, possible levels:
8181
debug, info, warning, error, critical)
8282
-i, --incremental incremental backup
83-
--incremental-by-files incremental backup using modified time of files
83+
--incremental-by-files
84+
incremental backup based on modification date of files
8485
--starred include JSON output of starred repositories in backup
8586
--all-starred include starred repositories in backup [*]
8687
--watched include JSON output of watched repositories in backup
@@ -100,20 +101,22 @@ CLI Help output::
100101
--milestones include milestones in backup
101102
--repositories include repository clone in backup
102103
--bare clone bare repositories
104+
--no-prune disable prune option for git fetch
103105
--lfs clone LFS repositories (requires Git LFS to be
104106
installed, https://git-lfs.github.com) [*]
105107
--wikis include wiki clone in backup
106108
--gists include gists in backup [*]
107109
--starred-gists include starred gists in backup [*]
110+
--skip-archived skip project if it is archived
108111
--skip-existing skip project if a backup directory exists
109-
-L [LANGUAGES [LANGUAGES ...]], --languages [LANGUAGES [LANGUAGES ...]]
112+
-L, --languages [LANGUAGES ...]
110113
only allow these languages
111-
-N NAME_REGEX, --name-regex NAME_REGEX
114+
-N, --name-regex NAME_REGEX
112115
python regex to match names against
113-
-H GITHUB_HOST, --github-host GITHUB_HOST
116+
-H, --github-host GITHUB_HOST
114117
GitHub Enterprise hostname
115118
-O, --organization whether or not this is an organization user
116-
-R REPOSITORY, --repository REPOSITORY
119+
-R, --repository REPOSITORY
117120
name of repository to limit backup to
118121
-P, --private include private repositories [*]
119122
-F, --fork include forked repositories [*]
@@ -128,26 +131,25 @@ CLI Help output::
128131
--releases include release information, not including assets or
129132
binaries
130133
--latest-releases NUMBER_OF_LATEST_RELEASES
131-
include certain number of the latest releases;
132-
only applies if including releases
133-
--skip-prerelease skip prerelease and draft versions; only applies if including releases
134+
include certain number of the latest releases; only
135+
applies if including releases
136+
--skip-prerelease skip prerelease and draft versions; only applies if
137+
including releases
134138
--assets include assets alongside release information; only
135139
applies if including releases
136-
--skip-assets-on [REPO ...]
137-
skip asset downloads for these repositories (e.g.
138-
--skip-assets-on repo1 owner/repo2)
139-
--attachments download user-attachments from issues and pull requests
140-
to issues/attachments/{issue_number}/ and
141-
pulls/attachments/{pull_number}/ directories
142-
--exclude [REPOSITORY [REPOSITORY ...]]
143-
names of repositories to exclude from backup.
140+
--skip-assets-on [SKIP_ASSETS_ON ...]
141+
skip asset downloads for these repositories
142+
--attachments download user-attachments from issues and pull
143+
requests
144144
--throttle-limit THROTTLE_LIMIT
145145
start throttling of GitHub API requests after this
146146
amount of API requests remain
147147
--throttle-pause THROTTLE_PAUSE
148148
wait this amount of seconds when API request
149149
throttling is active (default: 30.0, requires
150150
--throttle-limit to be set)
151+
--exclude [EXCLUDE ...]
152+
names of repositories to exclude
151153

152154

153155
Usage Details
@@ -156,13 +158,13 @@ Usage Details
156158
Authentication
157159
--------------
158160

159-
**Password-based authentication** will fail if you have two-factor authentication enabled, and will `be deprecated <https://github.blog/2023-03-09-raising-the-bar-for-software-security-github-2fa-begins-march-13/>`_ by 2023 EOY.
161+
GitHub requires token-based authentication for API access. Password authentication was `removed in November 2020 <https://developer.github.com/changes/2020-02-14-deprecating-password-auth/>`_.
160162

161-
``--username`` is used for basic password authentication and separate from the positional argument ``USER``, which specifies the user account you wish to back up.
163+
The positional argument ``USER`` specifies the user or organization account you wish to back up.
162164

163-
**Classic tokens** are `slightly less secure <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic>`_ as they provide very coarse-grained permissions.
165+
**Fine-grained tokens** (``-f TOKEN_FINE``) are recommended for most use cases, especially long-running backups (e.g. cron jobs), as they provide precise permission control.
164166

165-
If you need authentication for long-running backups (e.g. for a cron job) it is recommended to use **fine-grained personal access token** ``-f TOKEN_FINE``.
167+
**Classic tokens** (``-t TOKEN``) are `slightly less secure <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic>`_ as they provide very coarse-grained permissions.
166168

167169

168170
Fine Tokens

github_backup/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def main():
4343
if args.private and not get_auth(args):
4444
logger.warning(
4545
"The --private flag has no effect without authentication. "
46-
"Use -t/--token, -f/--token-fine, or -u/--username to authenticate."
46+
"Use -t/--token or -f/--token-fine to authenticate."
4747
)
4848

4949
if args.quiet:

github_backup/github_backup.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import calendar
88
import codecs
99
import errno
10-
import getpass
1110
import json
1211
import logging
1312
import os
@@ -24,7 +23,6 @@
2423
from datetime import datetime
2524
from http.client import IncompleteRead
2625
from urllib.error import HTTPError, URLError
27-
from urllib.parse import quote as urlquote
2826
from urllib.parse import urlencode, urlparse
2927
from urllib.request import HTTPRedirectHandler, Request, build_opener, urlopen
3028

@@ -149,17 +147,6 @@ def mask_password(url, secret="*****"):
149147
def parse_args(args=None):
150148
parser = argparse.ArgumentParser(description="Backup a github account")
151149
parser.add_argument("user", metavar="USER", type=str, help="github username")
152-
parser.add_argument(
153-
"-u", "--username", dest="username", help="username for basic auth"
154-
)
155-
parser.add_argument(
156-
"-p",
157-
"--password",
158-
dest="password",
159-
help="password for basic auth. "
160-
"If a username is given but not a password, the "
161-
"password will be prompted for.",
162-
)
163150
parser.add_argument(
164151
"-t",
165152
"--token",
@@ -533,16 +520,6 @@ def get_auth(args, encode=True, for_git_cli=False):
533520
auth = args.token_classic
534521
else:
535522
auth = "x-access-token:" + args.token_classic
536-
elif args.username:
537-
if not args.password:
538-
args.password = getpass.getpass()
539-
if encode:
540-
password = args.password
541-
else:
542-
password = urlquote(args.password)
543-
auth = args.username + ":" + password
544-
elif args.password:
545-
raise Exception("You must specify a username for basic auth")
546523

547524
if not auth:
548525
return None

tests/test_all_starred.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ def _create_mock_args(self, **overrides):
4646
args.prefer_ssh = False
4747
args.token_classic = None
4848
args.token_fine = None
49-
args.username = None
50-
args.password = None
5149
args.as_app = False
5250
args.osx_keychain_item_name = None
5351
args.osx_keychain_item_account = None

tests/test_attachments.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ def attachment_test_setup(tmp_path):
2424
args.as_app = False
2525
args.token_fine = None
2626
args.token_classic = None
27-
args.username = None
28-
args.password = None
2927
args.osx_keychain_item_name = None
3028
args.osx_keychain_item_account = None
3129
args.user = "testuser"

tests/test_http_451.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ def test_repository_unavailable_error_raised(self):
1717
args.as_app = False
1818
args.token_fine = None
1919
args.token_classic = None
20-
args.username = None
21-
args.password = None
2220
args.osx_keychain_item_name = None
2321
args.osx_keychain_item_account = None
2422
args.throttle_limit = None
@@ -52,8 +50,6 @@ def test_repository_unavailable_error_without_dmca_url(self):
5250
args.as_app = False
5351
args.token_fine = None
5452
args.token_classic = None
55-
args.username = None
56-
args.password = None
5753
args.osx_keychain_item_name = None
5854
args.osx_keychain_item_account = None
5955
args.throttle_limit = None
@@ -78,8 +74,6 @@ def test_repository_unavailable_error_with_malformed_json(self):
7874
args.as_app = False
7975
args.token_fine = None
8076
args.token_classic = None
81-
args.username = None
82-
args.password = None
8377
args.osx_keychain_item_name = None
8478
args.osx_keychain_item_account = None
8579
args.throttle_limit = None

tests/test_pagination.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ def mock_args():
4545
args.as_app = False
4646
args.token_fine = None
4747
args.token_classic = "fake_token"
48-
args.username = None
49-
args.password = None
5048
args.osx_keychain_item_name = None
5149
args.osx_keychain_item_account = None
5250
args.throttle_limit = None

tests/test_retrieve_data.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ def mock_args(self):
7070
args.as_app = False
7171
args.token_fine = None
7272
args.token_classic = "fake_token"
73-
args.username = None
74-
args.password = None
7573
args.osx_keychain_item_name = None
7674
args.osx_keychain_item_account = None
7775
args.throttle_limit = None
@@ -313,8 +311,6 @@ def mock_args(self):
313311
args.as_app = False
314312
args.token_fine = None
315313
args.token_classic = "fake_token"
316-
args.username = None
317-
args.password = None
318314
args.osx_keychain_item_name = None
319315
args.osx_keychain_item_account = None
320316
args.throttle_limit = 10 # Throttle when remaining <= 10
@@ -344,8 +340,6 @@ def mock_args(self):
344340
args.as_app = False
345341
args.token_fine = None
346342
args.token_classic = "fake_token"
347-
args.username = None
348-
args.password = None
349343
args.osx_keychain_item_name = None
350344
args.osx_keychain_item_account = None
351345
args.throttle_limit = None

tests/test_skip_assets_on.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ def _create_mock_args(self, **overrides):
4848
args.prefer_ssh = False
4949
args.token_classic = "test-token"
5050
args.token_fine = None
51-
args.username = None
52-
args.password = None
5351
args.as_app = False
5452
args.osx_keychain_item_name = None
5553
args.osx_keychain_item_account = None

0 commit comments

Comments
 (0)