Implement Bearer Auth (#1216)

This commit is contained in:
Batuhan Taskaya
2021-12-01 20:37:57 +03:00
committed by GitHub
parent 5bf696d113
commit 00b366a81f
6 changed files with 51 additions and 8 deletions

View File

@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Added support for receving multiple HTTP headers with the same name, individually. ([#1207](https://github.com/httpie/httpie/issues/1207)) - Added support for receving multiple HTTP headers with the same name, individually. ([#1207](https://github.com/httpie/httpie/issues/1207))
- Added support for keeping `://` in the URL argument to allow quick conversions of pasted URLs into HTTPie calls just by adding a space after the protocol name (`$ https ://pie.dev``https://pie.dev`). ([#1195](https://github.com/httpie/httpie/issues/1195)) - Added support for keeping `://` in the URL argument to allow quick conversions of pasted URLs into HTTPie calls just by adding a space after the protocol name (`$ https ://pie.dev``https://pie.dev`). ([#1195](https://github.com/httpie/httpie/issues/1195))
- Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/httpie/issues/1212)) - Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/httpie/issues/1212))
- Added support for `bearer` authentication method ([#1215](https://github.com/httpie/httpie/issues/1215)).
## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14) ## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14)

View File

@ -1003,10 +1003,10 @@ the [sessions](#sessions) feature.
https -A bearer -a token pie.dev/bearer https -A bearer -a token pie.dev/bearer
``` ```
### Empty password ### Password prompt
```bash ```bash
$ http -a username: pie.dev/headers $ http -a username pie.dev/basic-auth/username/password
``` ```
### Empty password ### Empty password
@ -1020,6 +1020,12 @@ $ http -a username:password pie.dev/basic-auth/username/password
Authentication information from your `~/.netrc` file is by default honored as well. Authentication information from your `~/.netrc` file is by default honored as well.
For example: For example:
```bash
$ cat ~/.netrc
machine pie.dev
login httpie
password test
``` ```
```bash ```bash

View File

@ -554,10 +554,11 @@ auth = parser.add_argument_group(title='Authentication')
auth.add_argument( auth.add_argument(
'--auth', '-a', '--auth', '-a',
default=None, default=None,
metavar='USER[:PASS]', metavar='USER[:PASS] | TOKEN',
help=''' help='''
If only the username is provided (-a username), HTTPie will prompt For username/password based authentication mechanisms (e.g
for the password. basic auth or digest auth) if only the username is provided
(-a username), HTTPie will prompt for the password.
''', ''',
) )

View File

@ -34,6 +34,16 @@ class HTTPBasicAuth(requests.auth.HTTPBasicAuth):
return f'Basic {token}' return f'Basic {token}'
class HTTPBearerAuth(requests.auth.AuthBase):
def __init__(self, token: str) -> None:
self.token = token
def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
request.headers['Authorization'] = f'Bearer {self.token}'
return request
class BasicAuthPlugin(BuiltinAuthPlugin): class BasicAuthPlugin(BuiltinAuthPlugin):
name = 'Basic HTTP auth' name = 'Basic HTTP auth'
auth_type = 'basic' auth_type = 'basic'
@ -56,3 +66,14 @@ class DigestAuthPlugin(BuiltinAuthPlugin):
password: str password: str
) -> requests.auth.HTTPDigestAuth: ) -> requests.auth.HTTPDigestAuth:
return requests.auth.HTTPDigestAuth(username, password) return requests.auth.HTTPDigestAuth(username, password)
class BearerAuthPlugin(BuiltinAuthPlugin):
name = 'Bearer HTTP Auth'
auth_type = 'bearer'
netrc_parse = False
auth_parse = False
# noinspection PyMethodOverriding
def get_auth(self, **kwargs) -> requests.auth.HTTPDigestAuth:
return HTTPBearerAuth(self.raw_auth)

View File

@ -1,5 +1,5 @@
from .manager import PluginManager from .manager import PluginManager
from .builtin import BasicAuthPlugin, DigestAuthPlugin from .builtin import BasicAuthPlugin, DigestAuthPlugin, BearerAuthPlugin
from ..output.formatters.headers import HeadersFormatter from ..output.formatters.headers import HeadersFormatter
from ..output.formatters.json import JSONFormatter from ..output.formatters.json import JSONFormatter
from ..output.formatters.xml import XMLFormatter from ..output.formatters.xml import XMLFormatter
@ -13,6 +13,7 @@ plugin_manager = PluginManager()
plugin_manager.register( plugin_manager.register(
BasicAuthPlugin, BasicAuthPlugin,
DigestAuthPlugin, DigestAuthPlugin,
BearerAuthPlugin,
HeadersFormatter, HeadersFormatter,
JSONFormatter, JSONFormatter,
XMLFormatter, XMLFormatter,

View File

@ -25,6 +25,19 @@ def test_digest_auth(httpbin_both, argument_name):
assert r.json == {'authenticated': True, 'user': 'user'} assert r.json == {'authenticated': True, 'user': 'user'}
@pytest.mark.parametrize('token', [
'token_1',
'long_token' * 5,
'user:style',
])
def test_bearer_auth(httpbin_both, token):
r = http('--auth-type', 'bearer', '--auth', token,
httpbin_both + '/bearer')
assert HTTP_OK in r
assert r.json == {'authenticated': True, 'token': token}
@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass', @mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
new=lambda self, prompt: 'password') new=lambda self, prompt: 'password')
def test_password_prompt(httpbin): def test_password_prompt(httpbin):