Giter Site home page Giter Site logo

flask-sentinel's Introduction

Flask-Sentinel

OAuth2 Provider currently supporting the Resource Owner Password Credentials Grant as described in Section 1.3.3 of RFC 6749.

Powered by Flask-OAuthlib, Redis and MongoDB.

Deployment

$ pip install flask-sentinel

Usage

Once the extension and its dependencies are installed, you can use it like any other Flask extension:

from flask import Flask
from flask.ext.sentinel import ResourceOwnerPasswordCredentials, oauth


app = Flask(__name__)

# optionally load settings from py module
app.config.from_object('settings')

@app.route('/endpoint')
@oauth.require_oauth()
def restricted_access():
    return "You made it through and accessed the protected resource!"

if __name__ == '__main__':
    ResourceOwnerPasswordCredentials(app)
    app.run(ssl_context='adhoc')

User and Client Management

You can create users and clients through the default management interface available at https://localhost:5000/oauth/management.

https://raw.githubusercontent.com/pyeve/flask-sentinel/master/static/console.png

You can override the default page above with your own. Just drop your custom management.html file in a templates folder residing in your application root.

This page can and should have restricted access. In order to achieve that, set SENTINEL_MANAGEMENT_USERNAME and SENTINEL_MANAGEMENT_PASSWORD in your application settings. This will fire up a Basic Auth dialog when the page is accessed with a browser.

Testing

After creating a user and client, you may use curl to test the application.

Generating a Bearer Token

$ curl -k -X POST -d "client_id=9qFbZD4udTzFVYo0u5UzkZX9iuzbdcJDRAquTfRk&grant_type=password&username=jonas&password=pass" https://localhost:5000/oauth/token
{"access_token": "NYODXSR8KalTPnWUib47t5E8Pi8mo4", "token_type": "Bearer", "refresh_token": "s6L6OPL2bnKSRSbgQM3g0wbFkJB4ML", "scope": ""}

Generating a Bearer Token Using a Retrieved Refresh Token

$ curl -X POST -d "client_id=9qFbZD4udTzFVYo0u5UzkZX9iuzbdcJDRAquTfRk&grant_type=refresh_token&refresh_token=s6L6OPL2bnKSRSbgQM3g0wbFkJB4ML" https://localhost:5000/oauth/token
{"access_token": "RmPAfqfsDoMCbQ2DUUehwcw1hMCMJj", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "s6L6OPL2bnKSRSbgQM3g0wbFkJB4ML", "scope": ""}

Accessing a Protected Resource Using Retrieved Bearer Token

$ curl -k -H "Authorization: Bearer NYODXSR8KalTPnWUib47t5E8Pi8mo4" https://localhost:5000/endpoint
You made it through and accessed the protected resource!

Configuration

Configuration works like any other Flask configuration. Here are the built-in defaults:

SENTINEL_ROUTE_PREFIX Default prefix for OAuth endpoints. Defaults to /oauth. Prepends both token and management urls.
SENTINEL_TOKEN_URL Url for token creation endpoint. Set to False to disable this feature. Defaults to /token, so the complete url is /oauth/token.
SENTINEL_MANAGEMENT_URL Url for management endpoint. Set to False to disable this feature. Defaults to /management, so the complete url is /oauth/management.
SENTINEL_REDIS_URL Url for the redis server. Defaults to redis://localhost:6379/0.
SENTINEL_MONGO_DBNAME Mongo database name. Defaults to oauth.
SENTINEL_MANAGEMENT_USERNAME Username needed to access the management page.
SENTINEL_MANAGEMENT_PASSWORD Password needed to access the management page.
OAUTH2_PROVIDER_ERROR_URI The error page when there is an error, default value is /oauth/errors.
OAUTH2_PROVIDER_TOKEN_EXPIRES_IN Default Bearer token expires time, default is 3600.
OAUTH2_PROVIDER_ERROR_ENDPOINT You can also configure the error page uri with an endpoint name.

Other standard PyMongo settings such as MONGO_HOST, MONGO_PORT, MONGO_URI are also supported; just prefix them with SENTINEL_ as seen above.

When a token is created it is added to both the database and the Redis cache. In Redis, key is the access token itself while value is the id of the user who requested the token. This allows for fast token authentication/verification bypassing the database lookup. This tecnique can be used, for example, when integrating flask-sentinel with Eve powered REST API instances.

Using Flask-Sentinel with Eve

See the Eve-OAuth2 example project.

Security

SSL/TLS

When working with OAuth 2.0, all communications must be encrypted with SSL/TLS. This example uses auto-generated SSL certificates, however in a production environment you should use a more formal, widely trusted certificate associated with your domain. In addition, requests should be handled by something like NGINX and proxied to the authentication service.

Note: Add `-k` to your `curl` arguments if you are working with an untrusted development server running under SSL/TLS.

Password Hashing

Bcrypt and a randomly generated salt are used to hash each user password before it is added to the database. You should never store passwords in plain text!

License

Flask-Sentinel is a Nicola Iarocci and Gestionali Amica open source project distributed under the BSD license.

Acknowledgement

This work is based on the yoloAPI project by Josh Brandoff and Jonas Brunsgaard.

flask-sentinel's People

Contributors

allanice001 avatar dependabot[bot] avatar nam4dev avatar nicolaiarocci avatar sillydan1 avatar vinyll avatar xuwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flask-sentinel's Issues

ResourceOwnerPasswordCredentials(app) fails with Unknown option config_prefix error

In pymongo 3.7.1 the MongoClient no longer accepts a keyword parameter config_prefix. This causes a failure when executing
ResourceOwnerPasswordCredentials(app)
I am not sure whether pymongo has a replacement for this functionality, but in any case it causes the whole system to not start up.

I subclassed ResourceOwnerPasswordCredentials and modified the init_app method to omit that parameter. Is there a more elegant solution?

Here is the stack trace:

Traceback (most recent call last):
  File "/home/cchayden/workspaces/mda/api/auth/run.py", line 56, in <module>
    ResourceOwnerPasswordCredentials(app)
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/flask_sentinel/flask_sentinel.py", line 22, in __init__
    self.init_app(app)
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/flask_sentinel/flask_sentinel.py", line 44, in init_app
    mongo.init_app(app, config_prefix='SENTINEL_MONGO')
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/flask_pymongo/__init__.py", line 160, in init_app
    self.cx = MongoClient(*args, **kwargs)
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/pymongo/mongo_client.py", line 521, in __init__
    for k, v in keyword_opts.items())
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/pymongo/mongo_client.py", line 521, in <genexpr>
    for k, v in keyword_opts.items())
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/pymongo/common.py", line 600, in validate
    value = validator(option, value)
  File "/home/cchayden/.virtualenvs/mongo/lib/python3.5/site-packages/pymongo/common.py", line 129, in raise_config_error
    raise ConfigurationError("Unknown option %s" % (key,))
pymongo.errors.ConfigurationError: Unknown option config_prefix

Error when load sentinel on Python 3.4

When try to load sentinel in python3.4, I have the error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/site-packages/flask/exthook.py", line 81, in load_module
    reraise(exc_type, exc_value, tb.tb_next)
  File "/usr/local/lib/python3.4/site-packages/flask/_compat.py", line 32, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.4/site-packages/flask_sentinel/__init__.py", line 1, in <module>
    from flask_sentinel import ResourceOwnerPasswordCredentials, oauth  # noqa
ImportError: cannot import name 'ResourceOwnerPasswordCredentials'

Client secret required ?

Hi good day,

I was going through your example ( the CURL request example ) using Postman ( https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en ) and i had an error after POSTing with my client_id, grant_type=password, username, and password:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Library/Python/2.7/site-packages/flask_oauthlib/provider/oauth2.py", line 467, in decorated
    uri, http_method, body, headers, credentials
  File "/Library/Python/2.7/site-packages/oauthlib/oauth2/rfc6749/endpoints/base.py", line 61, in wrapper
    return f(endpoint, uri, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/oauthlib/oauth2/rfc6749/endpoints/token.py", line 93, in create_token_response
    request, self.default_token_type)
  File "/Library/Python/2.7/site-packages/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py", line 92, in create_token_response
    if not self.request_validator.authenticate_client(request):
  File "/Library/Python/2.7/site-packages/flask_oauthlib/provider/oauth2.py", line 601, in authenticate_client
    if client.client_secret != client_secret:
AttributeError: 'Client' object has no attribute 'client_secret'

Apparently, I am required to pass a client_secret url parameter as well ? However, when i create a new client, I am only given the client_id, but not the client secret.

I've also tried adding in random strings for client_secret, but the same error occurs.

Am I missing anything ?

Cheers!

500 Error on correct username and password.

Everytime I am trying to generate accessToken using oauth/token I am getting this error
500 Internal Server Error Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
On checking pycharm console I see the following :-
redis.exceptions.DataError: Invalid input of type: 'ObjectId'. Convert to a byte, string or number first.

get token error

➜ flask-sentinel git:(develop) ✗ curl -k -X POST -d "client_id=o0DKRNzRNJouovo2oJupkto8jDFwa6NouU7cOQ5N&grant_type=password&username=test&password=1234Qwer" https://localhost:5000/oauth/token

<title>500 Internal Server Error</title>

Internal Server Error

The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

Error while trying to generate a new token :: 'bytes' object has no attribute 'encode'

There was an error while trying to generate a new token

$ curl -k -X POST -d "client_id=$TOKEN&grant_type=password&username=$USER&password=$PASS" https://$HOST:$PORT/oauth/token

...
...
...

Traceback (most recent call last):
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask_oauthlib/provider/oauth2.py", line 507, in decorated
    uri, http_method, body, headers, credentials
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/oauthlib/oauth2/rfc6749/endpoints/base.py", line 64, in wrapper
    return f(endpoint, uri, *args, **kwargs)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/oauthlib/oauth2/rfc6749/endpoints/token.py", line 111, in create_token_response
    request, self.default_token_type)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py", line 112, in create_token_response
    self.validate_token_request(request)
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py", line 187, in validate_token_request
    request.password, request.client, request):
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask_oauthlib/provider/oauth2.py", line 944, in validate_user
    username, password, client, request, *args, **kwargs
  File "/Users/k/.virtualenvs/oKW-apipub3/lib/python3.5/site-packages/flask_sentinel/data.py", line 108, in get_user
    user_hash = user['hashpw'].encode('utf-8')
AttributeError: 'bytes' object has no attribute 'encode'

Version and installed packages on this virtualenv

$ python -V
Python 3.5.2

$ pip list
bcrypt (3.1.1)
Cerberus (0.9.2)
cffi (1.8.3)
cryptography (1.5.2)
Eve (0.6.4)
Events (0.2.1)
Flask (0.10.1)
Flask-OAuthlib (0.9.3)
Flask-PyMongo (0.4.1)
Flask-Sentinel (0.0.5)
idna (2.1)
itsdangerous (0.24)
Jinja2 (2.8)
MarkupSafe (0.23)
oauthlib (2.0.0)
pip (8.1.2)
pyasn1 (0.1.9)
pycparser (2.14)
pymongo (3.3.0)
pyOpenSSL (16.1.0)
redis (2.10.5)
requests (2.11.1)
requests-oauthlib (0.7.0)
setuptools (28.3.0)
simplejson (3.8.2)
six (1.10.0)
Werkzeug (0.11.3)
wheel (0.30.0a0)

500 Internal Server Error When hit oauth/token endpoint

I install flask-sentinel and use the
curl -k -X POST -d "client_id=DN1KJb5kxpSUYxOSn8MZVLvXrtvPKjqqZ69GakjR&grant_type=password&username=test&password=test" https://127.0.0.1:5000/oauth/token
the username and password and client_id is created by the management, and the error is
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
Then I try the Postman tool, and the same error occured.
Please help me, Thanks a lot!

Breaking changes with werkzeug==1.0.0

Environment:

Python 3.7.6
Eve 1.1

Installed dependencies:

setuptools==41.0.1
flask-pymongo==0.5.2
redis==2.10.6
requests-oauthlib==1.1.0
eve==1.1
eve-swagger==0.0.11
Werkzeug==1.0.0
uwsgi==2.0.18
flask-cors==3.0.8
flask-sentinel==0.0.7
Traceback (most recent call last):
  File "wsgi.py", line 1, in <module>
    from server import app
  File "./server.py", line 2, in <module>
    from flask_sentinel import ResourceOwnerPasswordCredentials, oauth
  File "/usr/local/lib/python3.7/site-packages/flask_sentinel/__init__.py", line 1, in <module>
    from .flask_sentinel import ResourceOwnerPasswordCredentials, oauth  # noqa
  File "/usr/local/lib/python3.7/site-packages/flask_sentinel/flask_sentinel.py", line 11, in <module>
    from . import views
  File "/usr/local/lib/python3.7/site-packages/flask_sentinel/views.py", line 11, in <module>
    from .core import oauth
  File "/usr/local/lib/python3.7/site-packages/flask_sentinel/core.py", line 10, in <module>
    from flask_oauthlib.provider import OAuth2Provider
  File "/usr/local/lib/python3.7/site-packages/flask_oauthlib/provider/__init__.py", line 12, in <module>
    from .oauth1 import OAuth1Provider, OAuth1RequestValidator
  File "/usr/local/lib/python3.7/site-packages/flask_oauthlib/provider/oauth1.py", line 13, in <module>
    from werkzeug import cached_property
ImportError: cannot import name 'cached_property' from 'werkzeug' (/usr/local/lib/python3.7/site-packages/werkzeug/__init__.py)

As of now, I can only get to work with Werkzeug==0.16.1 only.

invalid_grant

Hi
How should i use password in curl ? the hash one or plain text one or ?!
because when i use hash pass :

<Response [401]> UNAUTHORIZED {'error': 'invalid_grant', 'error_description': 'Invalid credentials given.'}
and in server side :
"POST /oauth/token HTTP/1.1" 401 -

and when i use plain text pass :
<Response [500]> INTERNAL SERVER ERROR
and in server side :
redis.exceptions.ResponseError: NOAUTH Authentication required.

and this is my client sample code :
`
username = "b"
password = b'$2b$12$8HtqlhBjuaW2sVdQBDe2bOCV0yOfORsWMaY1EBmSeMTtg9Z4l7rsm'
headers = {"Content-Type": "application/x-www-form-urlencoded"}

data = {
"client_id": "5CxTuODAen7FgCsp75OVHXvxf4sWXHueW6pFWT3s",
"grant_type": "password",
"username": username,
"password": password
}

r = requests.Session()
r.mount("http://", HTTPAdapter(max_retries=30))
respauth = r.post(
url = "https://192.168.12.12:5555/oauth/token",
verify=False,
data=data
)
print(respauth)
`

and i use https://github.com/pyeve/eve-oauth2 code for server side code.

Authorization not working

Hello, I've been looking to implement this in my API, but there is a great big issue. The code example from "How to" doesn't really work and also flask.ext.sentinel is deprecated.

But it doesn't stop here. There is a way bigger issue. Authorization does not work for some weird reason. It puts data to both mongo and redis, it gives back token, but token itself does not work. Here, let me show you.

First we ask for a token:

$ curl -k -X POST -d "client_id=ByeNJDStsI13Hs8ztYXloMpGhsWGpsEfBUVtk5Jl&grant_type=password&username=reriiru&password=secret" http://localhost:5000/oauth/token

{"refresh_token": "C1YHlcWngjVp13LXwKcghINWG3iptt", "access_token": "BXNMYTKQUGMtlCWUHeTC2Qy1U8YiJ6", "token_type": "Bearer", "expires_in": 3600, "scope": ""}

Everything is fine. Then we try to use it to get to our endpoint:

$ curl -H "Authorisation: Bearer BXNMYTKQUGMtlCWUHeTC2Qy1U8YiJ6" http://127.0.0.1:5000/endpoint
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>401 Unauthorized</title>
<h1>Unauthorized</h1>
<p>The server could not verify that you are authorized to access the URL requested.  You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.</p>

And it sends us to hell! Instead we check up on mongo and redis and see what we get.

$ redis-cli
127.0.0.1:6379> get BXNMYTKQUGMtlCWUHeTC2Qy1U8YiJ6
"5970ad0468f165346f067fb2"
127.0.0.1:6379> 

$ mongo
MongoDB shell version: 3.2.11
connecting to: test
> use oauth
switched to db oauth
> db.tokens.find()
{ "_id" : ObjectId("5970e15d347fc57b83f1828b"), "user_id" : ObjectId("5970ad0468f165346f067fb2"), "expires" : ISODate("2017-07-20T17:59:09.312Z"), "refresh_token" : "C1YHlcWngjVp13LXwKcghINWG3iptt", "token_type" : "Bearer", "access_token" : "BXNMYTKQUGMtlCWUHeTC2Qy1U8YiJ6", "scopes" : [ "" ], "client_id" : "ByeNJDStsI13Hs8ztYXloMpGhsWGpsEfBUVtk5Jl", "user" : null }

Looks dandy to me. Everything is where is should be, except it has ObjectId in user_id in mongo for some reason. All the ID's match. And still it does not authorize my user. What went wrong, guys?

A hasty edit:
Here is the python version I am using:

$ python
Python 3.5.3+ (default, Jun  7 2017, 23:23:48)
[GCC 6.3.0 20170516] on linux

If needs be I can attach all the package versions in that venv.

Cannot import module

I downloaded flask-sentinel by pip like:

$ pip install flask-sentinel

When I try to import module, I am getting following error:

>>> from flask.ext.sentinel import oauth
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'flask.ext'

No module named 'flask.ext'

Also I am trying the following way too and getting different error:

>>> from flask_sentinel import oauth
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_sentinel\__init__.py", line 1, in <module>
    from .flask_sentinel import ResourceOwnerPasswordCredentials, oauth  # noqa
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_sentinel\flask_sentinel.py", line 11, in <module>
    from . import views
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_sentinel\views.py", line 11, in <module>
    from .core import oauth
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_sentinel\core.py", line 10, in <module>
    from flask_oauthlib.provider import OAuth2Provider
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_oauthlib\provider\__init__.py", line 12, in <module>
    from .oauth1 import OAuth1Provider, OAuth1RequestValidator
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_oauthlib\provider\oauth1.py", line 21, in <module>
    from ..utils import extract_params, create_response
  File "c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\flask_oauthlib\utils.py", line 5, in <module>
    from oauthlib.common import to_unicode, bytes_type
ImportError: cannot import name 'bytes_type' from 'oauthlib.common' (c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\oauthlib\common.py)

cannot import name 'bytes_type' from 'oauthlib.common' (c:\users\serhat\desktop\repos\python3-virtual\lib\site-packages\oauthlib\common.py)

v0.0.7 'save_token' is not handling 'access_token' typecasting according to how redis wants it

Whenever I try to perform an /oauth/token request, I get a 500 error (see below). I believe it is caused when saving the access token to the redis cache in data.py:161, where access_token is interpreted as an ObjectId which redis does not like. Could a simple string-cast fix this? Or maybe even casting it to a byte-array?

I tried to downgrade to v0.0.6, but it is using some super ancient version of flask-pymongo where the package naming is styled flask.ext.whatever and I would have to go VERY far back in time (4 years or so) to make that compatible, which is obviously not preferable.

Here's a tracedump:

rest_api | [2021-04-01 12:11:03,091] ERROR in app: Exception on /oauth/token [POST]
rest_api | Traceback (most recent call last):
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
rest_api |     response = self.full_dispatch_request()
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rest_api |     rv = self.handle_user_exception(e)
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
rest_api |     reraise(exc_type, exc_value, tb)
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
rest_api |     raise value
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rest_api |     rv = self.dispatch_request()
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
rest_api |     return self.view_functions[rule.endpoint](**req.view_args)
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask_oauthlib/provider/oauth2.py", line 507, in decorated
rest_api |     uri, http_method, body, headers, credentials
rest_api |   File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/endpoints/base.py", line 64, in wrapper
rest_api |     return f(endpoint, uri, *args, **kwargs)
rest_api |   File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/endpoints/token.py", line 117, in create_token_response
rest_api |     request, self.default_token_type)
rest_api |   File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py", line 109, in create_token_response
rest_api |     self.request_validator.save_token(token, request)
rest_api |   File "/usr/local/lib/python3.7/site-packages/oauthlib/oauth2/rfc6749/request_validator.py", line 246, in save_token
rest_api |     return self.save_bearer_token(token, request, *args, **kwargs)
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask_oauthlib/provider/oauth2.py", line 764, in save_bearer_token
rest_api |     self._tokensetter(token, request, *args, **kwargs)
rest_api |   File "/usr/local/lib/python3.7/site-packages/flask_sentinel/data.py", line 161, in save_token
rest_api |     redis.setex(token.access_token, expires_in, user_id)
rest_api |   File "/usr/local/lib/python3.7/site-packages/redis/client.py", line 1822, in setex
rest_api |     return self.execute_command('SETEX', name, time, value)
rest_api |   File "/usr/local/lib/python3.7/site-packages/redis/client.py", line 900, in execute_command
rest_api |     conn.send_command(*args)
rest_api |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 725, in send_command
rest_api |     self.send_packed_command(self.pack_command(*args),
rest_api |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 775, in pack_command
rest_api |     for arg in imap(self.encoder.encode, args):
rest_api |   File "/usr/local/lib/python3.7/site-packages/redis/connection.py", line 120, in encode
rest_api |     "bytes, string, int or float first." % typename)
rest_api | redis.exceptions.DataError: Invalid input of type: 'ObjectId'. Convert to a bytes, string, int or float first.
rest_api | 172.20.0.1 - - [01/Apr/2021 12:11:03] "POST /oauth/token HTTP/1.1" 500 -

Note: My setup is a network of docker containers, where flask-sentinel is used via eve, hence the rest_api name.

client secret

Hi I try to make it work but i still getting this traceback when im try to to the curl method to get a token

method : curl -k -X POST -d "client_id=8NuYg0th08PqLU7luqSwmFYfT1PQVQ16sFR5Yui1&grant_type=password&username=test&password=test" https://localhost:5000/oauth/token

log:

Traceback (most recent call last):
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/eve/flaskapp.py", line 929, in call
return super(Eve, self).call(environ, start_response)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1836, in call
return self.wsgi_app(environ, start_response)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functionsrule.endpoint
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask_oauthlib/provider/oauth2.py", line 489, in decorated
uri, http_method, body, headers, credentials
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/oauthlib/oauth2/rfc6749/endpoints/base.py", line 64, in wrapper
return f(endpoint, uri, _args, *_kwargs)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/oauthlib/oauth2/rfc6749/endpoints/token.py", line 100, in create_token_response
request, self.default_token_type)
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py", line 101, in create_token_response
if not self.request_validator.authenticate_client(request):
File "/home/operador/Documents/idinner/idinnerVE/lib/python2.7/site-packages/flask_oauthlib/provider/oauth2.py", line 607, in authenticate_client
if client.client_secret != client_secret:
AttributeError: 'Client' object has no attribute 'client_secret'

I have unistall all the package and I try to install again:
pip uninstall oauthlib
pip uninstall Flask-Oauthlib
pip uninstall flask-sentinel

and i install by pip install flask-sentinel getting the succesfull message "Installing collected packages: flask-sentinel, Flask-OAuthlib, oauthlib"

I saw in another post somebody has solved installing again the package but it didnt work for me

Do you know how to solve the problem?

user hash encoding with python 3

I notice that this bug (line 108 of data.py) has been fixed in the devel branch. I have installed the package with pip. Will you be updating it any time soon? Thanks

pip install breaks pip / fails

I've googled around and I think there's some kind of dependency problem; after installing flask-sentinel with pip, pip itself breaks (we get this error):
cffi.api.CDefError: 'point_conversion_form_t' has no values explicitly defined: refusing to guess which integer type it is meant to be (unsigned/signed, int/long)

It looks to be related to this discussion: graphite-project/graphite-web#1721, which in turn references others—but all of these look like they should be fixed at this point in time.

I'm able to fix pip with apt-get remove python-cffi, per this thread, but then attempts to pip install flask-sentinel result in some kind of cryptography compile error.

This issue may need to be passed along to whatever dependency is causing it, but as pip install flask-sentinel is the entry point for the problem for me, this seems like the best place to file the issue.

Create User Fails

Hi Nicola,

I think you have something wrong in the management.html template.

When you add new user the form post says:


But it looks like there is no action for "/"
I changed the html at line 35 with and it behaves well.

Cheers

Problem with flask config

Hello I've problem when changing sentinel config especially SENTINEL_MONGO_DBNAME and SENTINEL_MANAGEMENT_URL set to False

DBNAME not pointing in my db and I still can access sentinel management

Please help!!!

Pypi package not updated (0.0.5 vs 0.0.6)

The last changes has not been uploaded to PyPi.

The current version of this lib is 0.0.6, but at Pypi there is the 0.0.5 version.

https://pypi.python.org/pypi/Flask-Sentinel

Package Index > Flask-Sentinel > 0.0.5

Flask-Sentinel 0.0.5

Download Flask-Sentinel-0.0.5.tar.gz

OAuth2 Provider for Flask applications.

OAuth2 Provider currently supporting the Resource Owner Password Credentials Grant as described in Section 1.3.3 of RFC 6749.

Powered by Flask-OAuthlib, Redis and MongoDB.

Please, can it be updated? @nicolaiarocci

I suggest to integrate Travis or Drone to ensure automatic pip deployment while tagging new versions or merging to master.

Related to #16

Linking client_id to a specific endpoint

Ciao Nicola,
I was wondering: is there a way to associate a client_id with a specific endpoint?

Example:
Tokens created with client_id d1p4Kg7bS7M90XrseVeHa37lfAGCj8YgicVHlO93 are authorized to request just the https://api.website.com/people/ endpoint and nothing else. If a token created with another client_id requests the people endpoint a 401 error is returned.

I see that in the clients mongo collection there's a default_scope field which is always empty and in the tokens collection there's a scope field which is also always empty.
In your code I see that these scopes are empty by default and never gets filled with some value.
Maybe this code and field was a preparation for a future development?

Thank you in advance!
Andrea

Project Requires MongoDB, Doesn't provide other DB support.

This project looked really interesting until I read the words "mongodb". This is a blocker for me, but there is a greater issue that is actually worth reporting so here so I am:

The code is lacking a separation of concerns around data storage and usage. Looking at the code, this does seem to be the case.

The current interface is all static methods with no DB context or abstraction layer to allow other databases be used for data storage... so we cant even test if it actually works - as it a common need with oauth libs - without first setting up a MongoDB instance, and since MongoDB instances are a poison (its the wrong tool for the job 100% of the time due to its eventual consistency model, the a=inability to fail and recover gracefully, and lack of pure ACID support) nobody wants to do that.

Please support other databases.

[Documentation] Configuration `SENTINEL_PROVIDER_ROUTE_PREFIX` misspelled

Instead of SENTINEL_PROVIDER_ROUTE_PREFIX it should be SENTINEL_ROUTE_PREFIX.
For explanations:

class Config(object):
    def __init__(self, app):
        self.prefix = 'SENTINEL'
        ...
        # You're not using "PROVIDER_ROUTE_PREFIX" 
        # as your method _key only prefix with `SENTINEL`
        app.config.setdefault(self._key('ROUTE_PREFIX'), '/oauth')

Fix proposal, PR #13

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.