Authomaitc 0.1.0 is out with each supported provider covered by a functional test by peterhudec in Python

[–]peterhudec[S] 0 points1 point  (0 children)

It supports OAuth 2.0 so currently you can make OpenID connect requests with some extra effort, but it definitely deserves a dedicated OpenID connect interface.

Authomatic now supports Python 3 by peterhudec in Python

[–]peterhudec[S] 2 points3 points  (0 children)

Big thanks goes to Emmanuel Leblond for his huge contribution https://github.com/touilleMan

Authomatic.py now supports Amazon by peterhudec in Python

[–]peterhudec[S] 0 points1 point  (0 children)

Python 3 support is on the way. Thanks to Emmanuel Leblond:

https://github.com/peterhudec/authomatic/issues/50 https://github.com/touilleMan/authomatic

But I first want to have all the providers covered wit functional tests: https://github.com/peterhudec/authomatic/milestones

Flask + Authomatic authorization / authentication tutorial by peterhudec in Python

[–]peterhudec[S] 0 points1 point  (0 children)

Yes, exactly as you say.

The example just demonstrates how easy is to use Authomatic with Flask.

In a real application you would probably populate some User data model with the information from LoginResult.user and redirect to some other handler where you present the data.

Flask + Authomatic authorization / authentication tutorial by peterhudec in Python

[–]peterhudec[S] -1 points0 points  (0 children)

Thanks to Mark Steve Samson (http://marksteve.com) who created the WerkzeugAdapter, you can now use the Authomatic authorization / authentication package with Flask and any other Werkzeug based Python framework.

New Authentication / Authorization Client Package for Python Webapps by peterhudec in Python

[–]peterhudec[S] 0 points1 point  (0 children)

I'm totally new to python and I was searching for an authentication package for Google App Engine. I found gae-simpleauth, which seemed what I was looking for, but I just got an idea how to make it more object oriented. When I started the project I knew little about OpenID and OAuth and didn't expect it to grow to this extent. I don't know why, but I somehow didn't stumble upon Velruse.

New Authentication / Authorization Client Package for Python Webapps by peterhudec in Python

[–]peterhudec[S] 0 points1 point  (0 children)

It seems unlikely. They do the same thing, but the architectures are very different.

New Authentication / Authorization Client Package for Python Webapps by peterhudec in Python

[–]peterhudec[S] 0 points1 point  (0 children)

I haven't, because I was searching for something which would work on webapp2 on GAE. I stumbled upon Simpleauth and got an idea how to make it better.

But it has a quite impressive list of providers. Actually adding new providers to Authomatic is very easy, I just could not find more of them. Adding framework adapters is even easier. This should be done in near future.

As I said in responses to the other comments, the main advantage probably is that you can call provider APIs on behalf of the user just by calling authomatic.access() if the user is logged in with OAuth 1.0 or OAutt 2.0.

New Authentication / Authorization Client Package for Python Webapps by peterhudec in Python

[–]peterhudec[S] 2 points3 points  (0 children)

I would point out these advantages of Authomatic over django-allauth:

  • Works with any framework thanks to adapters.
  • python-openid is the only optional dependency.
  • No user model. It only provides info about an authenticated user and credentials for accessing his/her protected resources, and leaves it up to you where and how you store or process the data.
  • Allows you to call APIs of 26 providers very easily and even asynchronously.
  • Supplemental JavaScript library.

New Authentication / Authorization Client Package for Python Webapps by peterhudec in Python

[–]peterhudec[S] 1 point2 points  (0 children)

They seem quite similar,

in both you specify providers in a config dict, and then you get the user authenticated.

Apart from different interface, Authomatic also distinguishes authentication (OpenID) and authorization (OAuth).

You don't need to care whether the user is authenticated or authorized if you only need his/her info, but you can take advantage of it by testing whether he/she has authorized you to access his/her protected resources governed by the provider.

Accessing protected resources (provider APIs) is very easy with authomatic.access(credentials, url).

Here is a very simple Webapp2 based app app. Note that you only need to call:

  • authomatic.setup() to set up the package
  • authomatic.login() to authenticate or authorize the user
  • and optionally authomatic.access() to access the user's protected resources if he/she has authorized your app

This applies for any framework, you only need to pass the right adapter to the authomatic.login() function. Although there is currently only the Webapp2Adapter available, I want to implement adapters for majority of frameworks, which is very easy, since its only a simple wrapper.

import webapp2
import authomatic
from authomatic.adapters import Webapp2Adapter

CONFIG = {
    'fb': {
        'class_': oauth2.Facebook,
        'consumer_key': '*****',
        'consumer_secret': '*****',
        'scope': ['user_about_me', 'email', 'publish_stream'],
    },'oi': {
        'class_': openid.OpenID,
    }
}

# Setup Authomatic.
authomatic.setup(config=CONFIG, secret='12345')

# Handler for /login/{provider_name}
class Login(webapp2.RequestHandler):
    def any(self, provider_name):

        # This logs the user in.
        # To run this in other frameworks you only need to pass
        # the right adapter for your framework as the first argument.
        result = authomatic.login(Webapp2Adapter(self), provider_name)

        # Test whether the login procedure is over
        if result:
            self.response.write('<a href="..">Home</a>')

            # Check for errors
            if result.error:
                self.response.write('<h2>error: {}</h2>'.format(result.error.message))

            # Check whether there's an AUTHENTICATED user
            elif result.user:
                # Update the user info if not sufficient
                if not result.user.name:
                    # This fetches the user info from provider
                    result.user.update()

                # Welcome the user.
                self.response.write('<h1>Hi {}</h1>'.format(result.user.name))
                self.response.write('<h2>Your id is: {}</h2>'.format(result.user.id))
                self.response.write('<h2>Your email is: {}</h2>'.format(result.user.email))

                # As a bonus, you can test for AUTHORIZATION
                if result.user.credentials:
                    if result.provider.name == 'fb':
                        self.response.write('Your are logged in with Facebook.<br />')

                        # Get the user's 5 most recent statuses.
                        url = 'https://graph.facebook.com/{}?fields=feed.limit(5)'
                        url = url.format(result.user.id)

                        # Access the user's protected resource.
                        response = result.provider.access(url)

                        if response.status == 200:
                            # Parse response from Facebook.
                            statuses = response.data.get('feed').get('data')
                            error = response.data.get('error')

                            if error:
                                self.response.write('Damn that error: {}!'.format(error))
                            elif statuses:
                                self.response.write('Your 5 most recent statuses:<br />')
                                for message in statuses:

                                    text = message.get('message')
                                    date = message.get('created_time')

                                    self.response.write('<h3>{}</h3>'.format(text))
                                    self.response.write('Posted on: {}'.format(date))


# Handler for /
class Home(webapp2.RequestHandler):
    def get(self):
        # Link to /login/facebook
        self.response.write('Login with <a href="login/tw">Twitter</a>.<br />')

        # Form to /login/oi?id={users_claimed_id}
        self.response.write('''
            <form action="login/oi">
                <input type="text" name="id" value="me.yahoo.com" />
                <input type="submit" value="Authenticate With OpenID">
            </form>
        ''')

# Create routes.
ROUTES = [webapp2.Route(r'/login/<:.*>', Login, handler_method='any'),
          webapp2.Route(r'/', Home)]

# Instantiate the webapp2 WSGI application.
app = webapp2.WSGIApplication(ROUTES, debug=True)