Package: odre
Bottle extension class that provides user authentication based on thepgusersmodule.UsageYou just need to import theOdreobject, configure it and then use the@authenticateddecorator on any route you’d like authenticated:fromodreimportOdresample=Odre()@sample.get("/hello/<name>")@sample.authenticateddefhello(name):returnf"<p>Hello <b>{name}</b></p>"In the example above, when the route/hello/<name>is accessed for the first time, the user is shown a login form asking for credentials. Upon successful authentication, the user is supplied a token that is set either in a cookie or the client should supply it in the form of anAuthorization: Bearer <token>header.ConfigurationThe configuration is an .ini file similar to the following example:[app]name=SAMPLEcookie_name=sample_session_idroot_dir=/opt/webapp/dirlogin_page=/opt/webapp/dir/html/login.html[database]host=localhostport=5432user=sampleuserpassword=sampleuser[userspace]name=SAMPLE[smtp]host=mailhost.domain.comport=465The [app] sectionname:The name of the app. Must always be present.cookie_name:The name of the cookie that will be issued. This field is optional, if omitted the response to a successful login will be a json object with the token, which will be the responsibility of the front-end to send on every subsequent request in anAuthorization: Bearer <token>header.root_dir:The root directory of the application. This is useful to locate the app’s resources. Must always be present.login_page:The path to an html file that contains the login page. If omitted, a default login page will be issued, but it will be probably be too basic. The requirements for the login page are that it must send a form with the following fields:username,password, andproceed. Theproceedfield must be a hidden file set to{0}so thatOdrecan substitute it for the path that was originally requested and, upon a successful login, redirect the user there. Alternatively, the front-end can log-in using the pre-installed/loginroute sending username and password in a json object with aContent-typeheader set toapplication/jsonThe [userspace] sectionname:The name of thepgusersuserspace. Auserspace, is a PostgreSQL database that contains the users and sessions and is handled by thepgusersmodule.The [database] sectionThis section contains the parameters needed to connect to a PostgreSQL server. The fields are the same as those used to create a connection on thepsycopg2module.host:The host where the PostgreSQL resides. If omitted, a local connection through a unix-domain socket is assumed.port:The port where PostgreSQL listes. If omitted, Postgres default port 5432 is assumed.user:The PostgreSQL user.password:The password for the PostgreSQL user.The [smtp] sectionThis section contains the SMTP server parameters to send the user areset passwordtoken when such functionality is implemented.The APIapp = Odre(config=None)This is the class constructor.Odreis a subclass ofBottle, so all
of bottle’s functionality can be used, but there will be some additional methods
as well as a pre-installed/loginroute. The optional parameterconfigto
theOdreclass can be used to specify the appconfiguration. It can be:A string, which is interpreted as a filenameAny iterable yielding strings, e.g. a file-like object@app.authenticatedThis decorator, applied before any route (i.e.belowthe routes) marks a
function as accessible only to authenticated users. If the route is being requested
for the first time, or without a valid session token specified either in the
cookie or in a bearer authorisation header, or the token has expired, the
route will return the login html page specified in the configuration, or a
basic, default login page. Example:@app.get("/hello/<name>")@app.authenticateddefhello(name):returnf"<p>Hello <b>{name}</b></p>"app.configure(cp)This method configures theOdreobject if theconfigparameter was not
specified in the constructor.The argumentcpmust beConfigParserobject from theconfigparsermodule from the standard library, with the format specified in theconfigurationsection above.app.get_user_data()If the user has presented a valid session token, this method can be used to
retrieve information about the user. The result is a dictionary containing
the different fields. Example:@app.get("/hello/<name>")@authenticateddefhello(name):udata=app.get_user_data()returnf"""<p>Hello{name}, I know you are{udata['username']},
               your email is{udata['email']},
               you{"are"ifudata['admin']else"aren't"}an administrator,
               your user data is:{pformat(udata['extra_data'])}your session data is:{pformat(udata['session_data'])}</p>"""The/loginpre-installed routeClient apps that don’t want to present the user with the login html page for
any reason, can always request the/loginroute via thePOSThttp verb.
The route expects either a form with content typeapplication/x-www-form-urlencodedor anapplication/jsonwith the following fields:username:The usernamepassword:The passwordproceed:A relative URI to proceed to upon successful authentication. This field is optional
and defaults to ‘/’LicenseThis software is released with theMIT License