forked from extern/httpie-cli
Implement Bearer Auth (#1216)
This commit is contained in:
parent
5bf696d113
commit
00b366a81f
@ -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)
|
||||||
|
|
||||||
|
@ -1003,10 +1003,10 @@ the [sessions](#sessions) feature.
|
|||||||
|
|
||||||
The currently supported authentication schemes are Basic and Digest (see [auth plugins](#auth-plugins) for more). There are two flags that control authentication:
|
The currently supported authentication schemes are Basic and Digest (see [auth plugins](#auth-plugins) for more). There are two flags that control authentication:
|
||||||
|
|
||||||
| Flag | Arguments |
|
| Flag | Arguments |
|
||||||
| ----------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ----------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `--auth, -a` | Pass a `username:password` pair as the argument. Or, if you only specify a username (`-a username`), you’ll be prompted for the password before the request is sent. To send an empty password, pass `username:`. The `username:password@hostname` URL syntax is supported as well (but credentials passed via `-a` have higher priority) |
|
| `--auth, -a` | Pass either a `username:password` pair or a `token` as the argument. If the selected authenticated method requires username/password combination and if you only specify a username (`-a username`), you’ll be prompted for the password before the request is sent. To send an empty password, pass `username:`. The `username:password@hostname` URL syntax is supported as well (but credentials passed via `-a` have higher priority) |
|
||||||
| `--auth-type, -A` | Specify the auth mechanism. Possible values are `basic`, `digest`, or the name of any [auth plugins](#auth-plugins) you have installed. The default value is `basic` so it can often be omitted |
|
| `--auth-type, -A` | Specify the auth mechanism. Possible values are `basic`, `digest`, `bearer` or the name of any [auth plugins](#auth-plugins) you have installed. The default value is `basic` so it can often be omitted |
|
||||||
|
|
||||||
### Basic auth
|
### Basic auth
|
||||||
|
|
||||||
@ -1020,6 +1020,12 @@ $ http -a username:password pie.dev/basic-auth/username/password
|
|||||||
$ http -A digest -a username:password pie.dev/digest-auth/httpie/username/password
|
$ http -A digest -a username:password pie.dev/digest-auth/httpie/username/password
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Bearer auth
|
||||||
|
|
||||||
|
```bash
|
||||||
|
https -A bearer -a token pie.dev/bearer
|
||||||
|
```
|
||||||
|
|
||||||
### Password prompt
|
### Password prompt
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -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.
|
||||||
|
|
||||||
''',
|
''',
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user