Due to a limitation in SSSd, the new AAA system will provide the user's SSH keys base64-encoded. This change handles that while keeping compatibility.
@abompard Please rebase your PR onto current master. Your PR is based on a two-year-old reference point.
rebased onto 8b483d0e1511bec5888112ea47b6b7217a71ec7c
Oops, rebased, thanks.
This looks nice and thanks for the unit-tests!
10:43:51 ImportError while importing test module '/pagure/tests/test_pagure_flask_ui_oidc_login.py'. 10:43:51 Hint: make sure your test modules/packages have valid Python names. 10:43:51 Traceback: 10:43:51 tests/test_pagure_flask_ui_oidc_login.py:30: in <module> 10:43:51 from pagure.ui.oidc_login import fas_user_from_oidc, oidc 10:43:51 pagure/ui/oidc_login.py:26: in <module> 10:43:51 from flask_oidc import OpenIDConnect 10:43:51 E ModuleNotFoundError: No module named 'flask_oidc'
The containers and test requirements-test stuff need flask-oidc installed via RPMs and pip.
flask-oidc
@abompard did you see the failing test?
1 new commit added
Add a dependency on flask-oidc for testing
rebased onto c4a8ccc4ceb5d1ee11554053377889c1ad48a5cc
2 new commits added
In the new AAA system, the SSH key will be base64-encoded
OK, it fails because the CI system is determining the list of RPM dependencies by parsing the pagure.spec file before the new commits are merged. I'm trying to fix that. By the way, the EPEL7 version of the command line that does this (in centos7-rpms-py2) is pretty broken. Is CentOS 7 + Python 2 still a supported architecture?
pagure.spec
centos7-rpms-py2
CI: install new deps after merging the PR under test
Well, after we cut the Pagure 5.12 release, we intend to drop Python 2 support entirely. We don't have too many items left for doing that: https://pagure.io/pagure/roadmap/5.12/
git.centos.org still runs py2/centos7 so yes this is still a supported architecture for now.
What about adding the new dependency in a separate PR we merge first? Not ideal but prevents us from spending too much time on this
rebased onto 41ba84dd33e751b0c26cc7318c1500ffcd64e6a2
3 new commits added
rebased onto e62359135e068c2cfe16ad4e81e1e7c3481cb3b7
pretty please pagure-ci rebuild
rebased onto 94fbdec260440d823f97462d1044722f196aebc2
Looks like black is the remaining failing tests on the py3/rpm environment
rebased onto 4461797351acd7a48eb12f01cffc387dda0fe8f8
rebased onto 9b561f53e898a7b1100dba034692d5d8804e1b80
The errors seem valid \ó/
21:08:51 =================================== FAILURES =================================== 21:08:51 ______________ PagureFlaskOIDCLogintests.test_fas_user_from_oidc _______________ 21:08:51 [gw6] linux2 -- Python 2.7.5 /usr/bin/python 21:08:51 self = <tests.test_pagure_flask_ui_oidc_login.PagureFlaskOIDCLogintests testMethod=test_fas_user_from_oidc> 21:08:51 21:08:51 def setUp(self): 21:08:51 """ Create the application with PAGURE_AUTH being local. """ 21:08:51 super(PagureFlaskOIDCLogintests, self).setUp() 21:08:51 21:08:51 self.app = pagure.flask_app.create_app( 21:08:51 {"DB_URL": self.dbpath, "PAGURE_AUTH": "local"} 21:08:51 ) 21:08:51 # Remove the log handlers for the tests 21:08:51 self.app.logger.handlers = [] 21:08:51 21:08:51 secrets_path = os.path.join(self.path, "client_secrets.json") 21:08:51 self.config_patcher = patch.dict( 21:08:51 "pagure.config.config", 21:08:51 { 21:08:51 "OIDC_PAGURE_EMAIL": "email", 21:08:51 "OIDC_PAGURE_FULLNAME": "name", 21:08:51 "OIDC_PAGURE_USERNAME": "preferred_username", 21:08:51 "OIDC_PAGURE_SSH_KEY": "ssh_key", 21:08:51 "OIDC_PAGURE_GROUPS": "groups", 21:08:51 "OIDC_CLIENT_SECRETS": secrets_path, 21:08:51 }, 21:08:51 ) 21:08:51 self.config_patcher.start() 21:08:51 21:08:51 with open(secrets_path, "w") as secrets: 21:08:51 secrets.write(json.dumps(CLIENT_SECRETS)) 21:08:51 21:08:51 > oidc.init_app(self.app) 21:08:51 21:08:51 tests/test_pagure_flask_ui_oidc_login.py:77: 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 /usr/lib/python2.7/site-packages/flask_oidc/__init__.py:133: in init_app 21:08:51 scope=app.config['OIDC_SCOPES']) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/_helpers.py:133: in positional_wrapper 21:08:51 return wrapped(*args, **kwargs) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/client.py:2125: in flow_from_clientsecrets 21:08:51 cache=cache) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:165: in loadfile 21:08:51 return _loadfile(filename) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:126: in _loadfile 21:08:51 return _validate_clientsecrets(obj) 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 21:08:51 clientsecrets_dict = {'web': {'auth_uri': 'dummy-uri://', 'client_id': 'dummy', 'client_secret': 'dummy', 'token_uri': 'dummy-uri://', ...}} 21:08:51 21:08:51 def _validate_clientsecrets(clientsecrets_dict): 21:08:51 """Validate parsed client secrets from a file. 21:08:51 21:08:51 Args: 21:08:51 clientsecrets_dict: dict, a dictionary holding the client secrets. 21:08:51 21:08:51 Returns: 21:08:51 tuple, a string of the client type and the information parsed 21:08:51 from the file. 21:08:51 """ 21:08:51 _INVALID_FILE_FORMAT_MSG = ( 21:08:51 'Invalid file format. See ' 21:08:51 'https://developers.google.com/api-client-library/' 21:08:51 'python/guide/aaa_client_secrets') 21:08:51 21:08:51 if clientsecrets_dict is None: 21:08:51 raise InvalidClientSecretsError(_INVALID_FILE_FORMAT_MSG) 21:08:51 try: 21:08:51 (client_type, client_info), = clientsecrets_dict.items() 21:08:51 except (ValueError, AttributeError): 21:08:51 raise InvalidClientSecretsError( 21:08:51 _INVALID_FILE_FORMAT_MSG + ' ' 21:08:51 'Expected a JSON object with a single property for a "web" or ' 21:08:51 '"installed" application') 21:08:51 21:08:51 if client_type not in VALID_CLIENT: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Unknown client type: {0}.'.format(client_type)) 21:08:51 21:08:51 for prop_name in VALID_CLIENT[client_type]['required']: 21:08:51 if prop_name not in client_info: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Missing property "{0}" in a client type of "{1}".'.format( 21:08:51 > prop_name, client_type)) 21:08:51 E InvalidClientSecretsError: Missing property "redirect_uris" in a client type of "web". 21:08:51 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:101: InvalidClientSecretsError 21:08:51 ___________ PagureFlaskOIDCLogintests.test_fas_user_from_oidc_groups ___________ 21:08:51 [gw6] linux2 -- Python 2.7.5 /usr/bin/python 21:08:51 self = <tests.test_pagure_flask_ui_oidc_login.PagureFlaskOIDCLogintests testMethod=test_fas_user_from_oidc_groups> 21:08:51 21:08:51 def setUp(self): 21:08:51 """ Create the application with PAGURE_AUTH being local. """ 21:08:51 super(PagureFlaskOIDCLogintests, self).setUp() 21:08:51 21:08:51 self.app = pagure.flask_app.create_app( 21:08:51 {"DB_URL": self.dbpath, "PAGURE_AUTH": "local"} 21:08:51 ) 21:08:51 # Remove the log handlers for the tests 21:08:51 self.app.logger.handlers = [] 21:08:51 21:08:51 secrets_path = os.path.join(self.path, "client_secrets.json") 21:08:51 self.config_patcher = patch.dict( 21:08:51 "pagure.config.config", 21:08:51 { 21:08:51 "OIDC_PAGURE_EMAIL": "email", 21:08:51 "OIDC_PAGURE_FULLNAME": "name", 21:08:51 "OIDC_PAGURE_USERNAME": "preferred_username", 21:08:51 "OIDC_PAGURE_SSH_KEY": "ssh_key", 21:08:51 "OIDC_PAGURE_GROUPS": "groups", 21:08:51 "OIDC_CLIENT_SECRETS": secrets_path, 21:08:51 }, 21:08:51 ) 21:08:51 self.config_patcher.start() 21:08:51 21:08:51 with open(secrets_path, "w") as secrets: 21:08:51 secrets.write(json.dumps(CLIENT_SECRETS)) 21:08:51 21:08:51 > oidc.init_app(self.app) 21:08:51 21:08:51 tests/test_pagure_flask_ui_oidc_login.py:77: 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 /usr/lib/python2.7/site-packages/flask_oidc/__init__.py:133: in init_app 21:08:51 scope=app.config['OIDC_SCOPES']) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/_helpers.py:133: in positional_wrapper 21:08:51 return wrapped(*args, **kwargs) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/client.py:2125: in flow_from_clientsecrets 21:08:51 cache=cache) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:165: in loadfile 21:08:51 return _loadfile(filename) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:126: in _loadfile 21:08:51 return _validate_clientsecrets(obj) 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 21:08:51 clientsecrets_dict = {'web': {'auth_uri': 'dummy-uri://', 'client_id': 'dummy', 'client_secret': 'dummy', 'token_uri': 'dummy-uri://', ...}} 21:08:51 21:08:51 def _validate_clientsecrets(clientsecrets_dict): 21:08:51 """Validate parsed client secrets from a file. 21:08:51 21:08:51 Args: 21:08:51 clientsecrets_dict: dict, a dictionary holding the client secrets. 21:08:51 21:08:51 Returns: 21:08:51 tuple, a string of the client type and the information parsed 21:08:51 from the file. 21:08:51 """ 21:08:51 _INVALID_FILE_FORMAT_MSG = ( 21:08:51 'Invalid file format. See ' 21:08:51 'https://developers.google.com/api-client-library/' 21:08:51 'python/guide/aaa_client_secrets') 21:08:51 21:08:51 if clientsecrets_dict is None: 21:08:51 raise InvalidClientSecretsError(_INVALID_FILE_FORMAT_MSG) 21:08:51 try: 21:08:51 (client_type, client_info), = clientsecrets_dict.items() 21:08:51 except (ValueError, AttributeError): 21:08:51 raise InvalidClientSecretsError( 21:08:51 _INVALID_FILE_FORMAT_MSG + ' ' 21:08:51 'Expected a JSON object with a single property for a "web" or ' 21:08:51 '"installed" application') 21:08:51 21:08:51 if client_type not in VALID_CLIENT: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Unknown client type: {0}.'.format(client_type)) 21:08:51 21:08:51 for prop_name in VALID_CLIENT[client_type]['required']: 21:08:51 if prop_name not in client_info: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Missing property "{0}" in a client type of "{1}".'.format( 21:08:51 > prop_name, client_type)) 21:08:51 E InvalidClientSecretsError: Missing property "redirect_uris" in a client type of "web". 21:08:51 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:101: InvalidClientSecretsError 21:08:51 ____________ PagureFlaskOIDCLogintests.test_fas_user_from_oidc_ssh _____________ 21:08:51 [gw6] linux2 -- Python 2.7.5 /usr/bin/python 21:08:51 self = <tests.test_pagure_flask_ui_oidc_login.PagureFlaskOIDCLogintests testMethod=test_fas_user_from_oidc_ssh> 21:08:51 21:08:51 def setUp(self): 21:08:51 """ Create the application with PAGURE_AUTH being local. """ 21:08:51 super(PagureFlaskOIDCLogintests, self).setUp() 21:08:51 21:08:51 self.app = pagure.flask_app.create_app( 21:08:51 {"DB_URL": self.dbpath, "PAGURE_AUTH": "local"} 21:08:51 ) 21:08:51 # Remove the log handlers for the tests 21:08:51 self.app.logger.handlers = [] 21:08:51 21:08:51 secrets_path = os.path.join(self.path, "client_secrets.json") 21:08:51 self.config_patcher = patch.dict( 21:08:51 "pagure.config.config", 21:08:51 { 21:08:51 "OIDC_PAGURE_EMAIL": "email", 21:08:51 "OIDC_PAGURE_FULLNAME": "name", 21:08:51 "OIDC_PAGURE_USERNAME": "preferred_username", 21:08:51 "OIDC_PAGURE_SSH_KEY": "ssh_key", 21:08:51 "OIDC_PAGURE_GROUPS": "groups", 21:08:51 "OIDC_CLIENT_SECRETS": secrets_path, 21:08:51 }, 21:08:51 ) 21:08:51 self.config_patcher.start() 21:08:51 21:08:51 with open(secrets_path, "w") as secrets: 21:08:51 secrets.write(json.dumps(CLIENT_SECRETS)) 21:08:51 21:08:51 > oidc.init_app(self.app) 21:08:51 21:08:51 tests/test_pagure_flask_ui_oidc_login.py:77: 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 /usr/lib/python2.7/site-packages/flask_oidc/__init__.py:133: in init_app 21:08:51 scope=app.config['OIDC_SCOPES']) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/_helpers.py:133: in positional_wrapper 21:08:51 return wrapped(*args, **kwargs) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/client.py:2125: in flow_from_clientsecrets 21:08:51 cache=cache) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:165: in loadfile 21:08:51 return _loadfile(filename) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:126: in _loadfile 21:08:51 return _validate_clientsecrets(obj) 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 21:08:51 clientsecrets_dict = {'web': {'auth_uri': 'dummy-uri://', 'client_id': 'dummy', 'client_secret': 'dummy', 'token_uri': 'dummy-uri://', ...}} 21:08:51 21:08:51 def _validate_clientsecrets(clientsecrets_dict): 21:08:51 """Validate parsed client secrets from a file. 21:08:51 21:08:51 Args: 21:08:51 clientsecrets_dict: dict, a dictionary holding the client secrets. 21:08:51 21:08:51 Returns: 21:08:51 tuple, a string of the client type and the information parsed 21:08:51 from the file. 21:08:51 """ 21:08:51 _INVALID_FILE_FORMAT_MSG = ( 21:08:51 'Invalid file format. See ' 21:08:51 'https://developers.google.com/api-client-library/' 21:08:51 'python/guide/aaa_client_secrets') 21:08:51 21:08:51 if clientsecrets_dict is None: 21:08:51 raise InvalidClientSecretsError(_INVALID_FILE_FORMAT_MSG) 21:08:51 try: 21:08:51 (client_type, client_info), = clientsecrets_dict.items() 21:08:51 except (ValueError, AttributeError): 21:08:51 raise InvalidClientSecretsError( 21:08:51 _INVALID_FILE_FORMAT_MSG + ' ' 21:08:51 'Expected a JSON object with a single property for a "web" or ' 21:08:51 '"installed" application') 21:08:51 21:08:51 if client_type not in VALID_CLIENT: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Unknown client type: {0}.'.format(client_type)) 21:08:51 21:08:51 for prop_name in VALID_CLIENT[client_type]['required']: 21:08:51 if prop_name not in client_info: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Missing property "{0}" in a client type of "{1}".'.format( 21:08:51 > prop_name, client_type)) 21:08:51 E InvalidClientSecretsError: Missing property "redirect_uris" in a client type of "web". 21:08:51 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:101: InvalidClientSecretsError 21:08:51 __________ PagureFlaskOIDCLogintests.test_fas_user_from_oidc_ssh_b64 ___________ 21:08:51 [gw6] linux2 -- Python 2.7.5 /usr/bin/python 21:08:51 self = <tests.test_pagure_flask_ui_oidc_login.PagureFlaskOIDCLogintests testMethod=test_fas_user_from_oidc_ssh_b64> 21:08:51 21:08:51 def setUp(self): 21:08:51 """ Create the application with PAGURE_AUTH being local. """ 21:08:51 super(PagureFlaskOIDCLogintests, self).setUp() 21:08:51 21:08:51 self.app = pagure.flask_app.create_app( 21:08:51 {"DB_URL": self.dbpath, "PAGURE_AUTH": "local"} 21:08:51 ) 21:08:51 # Remove the log handlers for the tests 21:08:51 self.app.logger.handlers = [] 21:08:51 21:08:51 secrets_path = os.path.join(self.path, "client_secrets.json") 21:08:51 self.config_patcher = patch.dict( 21:08:51 "pagure.config.config", 21:08:51 { 21:08:51 "OIDC_PAGURE_EMAIL": "email", 21:08:51 "OIDC_PAGURE_FULLNAME": "name", 21:08:51 "OIDC_PAGURE_USERNAME": "preferred_username", 21:08:51 "OIDC_PAGURE_SSH_KEY": "ssh_key", 21:08:51 "OIDC_PAGURE_GROUPS": "groups", 21:08:51 "OIDC_CLIENT_SECRETS": secrets_path, 21:08:51 }, 21:08:51 ) 21:08:51 self.config_patcher.start() 21:08:51 21:08:51 with open(secrets_path, "w") as secrets: 21:08:51 secrets.write(json.dumps(CLIENT_SECRETS)) 21:08:51 21:08:51 > oidc.init_app(self.app) 21:08:51 21:08:51 tests/test_pagure_flask_ui_oidc_login.py:77: 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 /usr/lib/python2.7/site-packages/flask_oidc/__init__.py:133: in init_app 21:08:51 scope=app.config['OIDC_SCOPES']) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/_helpers.py:133: in positional_wrapper 21:08:51 return wrapped(*args, **kwargs) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/client.py:2125: in flow_from_clientsecrets 21:08:51 cache=cache) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:165: in loadfile 21:08:51 return _loadfile(filename) 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:126: in _loadfile 21:08:51 return _validate_clientsecrets(obj) 21:08:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 21:08:51 21:08:51 clientsecrets_dict = {'web': {'auth_uri': 'dummy-uri://', 'client_id': 'dummy', 'client_secret': 'dummy', 'token_uri': 'dummy-uri://', ...}} 21:08:51 21:08:51 def _validate_clientsecrets(clientsecrets_dict): 21:08:51 """Validate parsed client secrets from a file. 21:08:51 21:08:51 Args: 21:08:51 clientsecrets_dict: dict, a dictionary holding the client secrets. 21:08:51 21:08:51 Returns: 21:08:51 tuple, a string of the client type and the information parsed 21:08:51 from the file. 21:08:51 """ 21:08:51 _INVALID_FILE_FORMAT_MSG = ( 21:08:51 'Invalid file format. See ' 21:08:51 'https://developers.google.com/api-client-library/' 21:08:51 'python/guide/aaa_client_secrets') 21:08:51 21:08:51 if clientsecrets_dict is None: 21:08:51 raise InvalidClientSecretsError(_INVALID_FILE_FORMAT_MSG) 21:08:51 try: 21:08:51 (client_type, client_info), = clientsecrets_dict.items() 21:08:51 except (ValueError, AttributeError): 21:08:51 raise InvalidClientSecretsError( 21:08:51 _INVALID_FILE_FORMAT_MSG + ' ' 21:08:51 'Expected a JSON object with a single property for a "web" or ' 21:08:51 '"installed" application') 21:08:51 21:08:51 if client_type not in VALID_CLIENT: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Unknown client type: {0}.'.format(client_type)) 21:08:51 21:08:51 for prop_name in VALID_CLIENT[client_type]['required']: 21:08:51 if prop_name not in client_info: 21:08:51 raise InvalidClientSecretsError( 21:08:51 'Missing property "{0}" in a client type of "{1}".'.format( 21:08:51 > prop_name, client_type)) 21:08:51 E InvalidClientSecretsError: Missing property "redirect_uris" in a client type of "web". 21:08:51 21:08:51 /usr/lib/python2.7/site-packages/oauth2client/clientsecrets.py:101: InvalidClientSecretsError
rebased onto 6a9880c4cfe2de46076640b199288ad9aea55f05
rebased onto 3e82694b36b9245a9f2d55115729a90c3c8d428c
rebased onto a57f3f5e80699c5154aecc68b2de1fffcf186b73
Error: error creating build container: Error initializing source docker://quay.io/fedora/fedora:32: Error reading manifest 32 in quay.io/fedora/fedora: unknown: Tag 32 was deleted or has expired. To pull, revive via time machine
Seems unrelated, this time.
rebased onto e0bf71a22beb68575f9cf7e0ef2442fcd1f79d9a
Only one left:
13:01:51 def test_fas_user_from_oidc_ssh(self): 13:01:51 """ Test the user creation function. """ 13:01:51 user_info = self.user_info.copy() 13:01:51 user_info["ssh_key"] = "dummy ssh key" 13:01:51 flask.g._oidc_userinfo = user_info 13:01:51 > fas_user_from_oidc() 13:01:51 13:01:51 tests/test_pagure_flask_ui_oidc_login.py:119: 13:01:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 13:01:51 pagure/ui/oidc_login.py:59: in fas_user_from_oidc 13:01:51 ssh_key = b64decode(ssh_key).decode("ascii") 13:01:51 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 13:01:51 13:01:51 s = b'dummy ssh key', altchars = None, validate = False 13:01:51 13:01:51 def b64decode(s, altchars=None, validate=False): 13:01:51 """Decode the Base64 encoded bytes-like object or ASCII string s. 13:01:51 13:01:51 Optional altchars must be a bytes-like object or ASCII string of length 2 13:01:51 which specifies the alternative alphabet used instead of the '+' and '/' 13:01:51 characters. 13:01:51 13:01:51 The result is returned as a bytes object. A binascii.Error is raised if 13:01:51 s is incorrectly padded. 13:01:51 13:01:51 If validate is False (the default), characters that are neither in the 13:01:51 normal base-64 alphabet nor the alternative alphabet are discarded prior 13:01:51 to the padding check. If validate is True, these non-alphabet characters 13:01:51 in the input result in a binascii.Error. 13:01:51 """ 13:01:51 s = _bytes_from_decode_data(s) 13:01:51 if altchars is not None: 13:01:51 altchars = _bytes_from_decode_data(altchars) 13:01:51 assert len(altchars) == 2, repr(altchars) 13:01:51 s = s.translate(bytes.maketrans(altchars, b'+/')) 13:01:51 if validate and not re.fullmatch(b'[A-Za-z0-9+/]*={0,2}', s): 13:01:51 raise binascii.Error('Non-base64 digit found') 13:01:51 > return binascii.a2b_base64(s) 13:01:51 E binascii.Error: Incorrect padding 13:01:51 13:01:51 /usr/lib64/python3.8/base64.py:87: Error
rebased onto 02f9d0d6e306509803876f59b4613265d755e24c
rebased onto 5d86053abc278fb5448b508cee92bcd1beb3e3c8
Success at last, @pingou :-)
Let's get it in before it changes its mind! :D
Pull-Request has been merged by pingou
Due to a limitation in SSSd, the new AAA system will provide the user's SSH keys base64-encoded. This change handles that while keeping compatibility.