<commit_before>.. _oauth2:

OAuth2 Server
=============

An OAuth2 server concerns how to grant the auothorization and how to protect
the resource. Register an **OAuth** provider::

    from flask_oauthlib.provider import OAuth2Provider

    app = Flask(__name__)
    oauth = OAuth2Provider(app)

Like any other Flask extensions, we can pass the application later::

    oauth = OAuth2Provider()

    def create_app():
        app = Flask(__name__)
        oauth.init_app(app)
        return app

To implemente the oauthorization flow, we need to understand the data model.

User (Resource Owner)
---------------------

A user, or resource owner, is usally the registered user on your site. You
design your own user model, there is not much to say.

Client (Application)
---------------------

A client is the app which want to use the resource of a user. It is suggested
that the client is registered by a user on your site, but it is not required.

The client should contain at least these information:

- client_id: A random string
- client_secret: A random string
- client_type: A string represents if it is `confidential`
- redirect_uris: A list of redirect uris
- default_redirect_uri: One of the redirect uris
- default_scopes: Default scopes of the client

But it could be better, if you implemented:

- allowed_grant_types: A list of grant types
- allowed_response_types: A list of response types
- validate_scopes: A function to validate scopes

An example of the data model in SQLAlchemy (SQLAlchemy is not required)::

    class Client(db.Model):
        # human readable name, not required
        name = db.Column(db.Unicode(40))

        # human readable description, not required
        description = db.Column(db.Unicode(400))

        # creator of the client, not required
        user_id = db.Column(db.ForeignKey('user.id'))
        # required if you need to support client credential
        user = relationship('User')

        client_id = db.Column(db.Unicode(40), primary_key=True)
        client_secret = db.Column(db.Unicode(55), unique=True, index=True,
                                  nullable=False)

        # public or confidential
        is_confidential = db.Column(db.Boolean)

        _redirect_uris = db.Column(db.UnicodeText)
        _default_scopes = db.Column(db.UnicodeText)

        @property
        def client_type(self):
            if self.is_confidential:
                return 'confidential'
            return 'public'<commit_msg>Add note for scopes in documentation.<commit_after>.. _oauth2:

OAuth2 Server
=============

An OAuth2 server concerns how to grant the auothorization and how to protect
the resource. Register an **OAuth** provider::

    from flask_oauthlib.provider import OAuth2Provider

    app = Flask(__name__)
    oauth = OAuth2Provider(app)

Like any other Flask extensions, we can pass the application later::

    oauth = OAuth2Provider()

    def create_app():
        app = Flask(__name__)
        oauth.init_app(app)
        return app

To implemente the oauthorization flow, we need to understand the data model.

User (Resource Owner)
---------------------

A user, or resource owner, is usally the registered user on your site. You
design your own user model, there is not much to say.

Client (Application)
---------------------

A client is the app which want to use the resource of a user. It is suggested
that the client is registered by a user on your site, but it is not required.

The client should contain at least these information:

- client_id: A random string
- client_secret: A random string
- client_type: A string represents if it is `confidential`
- redirect_uris: A list of redirect uris
- default_redirect_uri: One of the redirect uris
- default_scopes: Default scopes of the client

But it could be better, if you implemented:

- allowed_grant_types: A list of grant types
- allowed_response_types: A list of response types
- validate_scopes: A function to validate scopes

.. note::

    The value of the scope parameter is expressed as a list of space-
    delimited, case-sensitive strings.

    via: http://tools.ietf.org/html/rfc6749#section-3.3

An example of the data model in SQLAlchemy (SQLAlchemy is not required)::

    class Client(db.Model):
        # human readable name, not required
        name = db.Column(db.Unicode(40))

        # human readable description, not required
        description = db.Column(db.Unicode(400))

        # creator of the client, not required
        user_id = db.Column(db.ForeignKey('user.id'))
        # required if you need to support client credential
        user = relationship('User')

        client_id = db.Column(db.Unicode(40), primary_key=True)
        client_secret = db.Column(db.Unicode(55), unique=True, index=True,
                                  nullable=False)

        # public or confidential
        is_confidential = db.Column(db.Boolean)

        _redirect_uris = db.Column(db.UnicodeText)
        _default_scopes = db.Column(db.UnicodeText)

        @property
        def client_type(self):
            if self.is_confidential:
                return 'confidential'
            return 'public'
{'fraction_non_alphanumeric': 0.0886566008517228, 'fraction_numerical': 0.006968641114982578, 'mean_word_length': 2.818920916481892, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5474105', 'n_tokens_mistral': 1449, 'n_tokens_neox': 1402, 'n_words': 555}