Skip to content

Commit

Permalink
Merge pull request SoftwareDefinedBuildings#25 from rajasriramoju/24-…
Browse files Browse the repository at this point in the history
…merge-login

24 merge login
  • Loading branch information
rajasriramoju authored May 6, 2019
2 parents 7809048 + 8989ce2 commit a270453
Show file tree
Hide file tree
Showing 20 changed files with 990 additions and 504 deletions.
4 changes: 4 additions & 0 deletions dashboards/solarplus-ui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.env
*.json
*.egg-info
config.py
94 changes: 94 additions & 0 deletions dashboards/solarplus-ui/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
okta-flask-example
==================

A simple Flask app with user registration and login.


Meta
----

- Author: Randall Degges
- Email: [email protected]
- Site: https://www.rdegges.com


Purpose
-------

This example app showcases how you can easily add user login, registration, etc.
into a Flask web app using OpenID Connect and `Okta
<https://developer.okta.com>`_.

I wrote this to showcase how to get stuff working in a simple way.

.. note::

I wrote a blog post showcasing how this example app was built. You can view it
here: https://developer.okta.com/blog/2018/07/12/flask-tutorial-simple-user-registration-and-login


Installation
------------

To install the sample app you need to have Python 2.7 or 3.4+ installed. You can
then install the project dependencies by running:

.. code-block:: console
$ pip install -e .
This will install all the project dependencies.


Running the App
---------------

This app requires Okta to run. Okta is a free-to-use API service that stores
user accounts and makes authentication and authorization simpler. Go create a
free Okta developer account before continuing: https://developer.okta.com/signup

Next, you need to create a ``client_secrets.json`` file. This holds the OpenID
Connect information necessary for the app to function. Create a file named
``client_secrets.json`` in the root of your project folder and add the following
contents.

.. code-block:: json
{
"web": {
"client_id": "{{ OKTA_CLIENT_ID }}",
"client_secret": "{{ OKTA_CLIENT_SECRET }}",
"auth_uri": "{{ OKTA_ORG_URL }}/oauth2/default/v1/authorize",
"token_uri": "{{ OKTA_ORG_URL }}/oauth2/default/v1/token",
"issuer": "{{ OKTA_ORG_URL }}/oauth2/default",
"userinfo_uri": "{{ OKTA_ORG_URL }}/oauth2/default/userinfo",
"redirect_uris": [
"http://localhost:5000",
"http://localhost:5000/oidc/callback"
]
}
}
.. note::

Be sure to replace the Okta variables above appropriately.

Next, define some necessary environment variables.

.. code-block:: console
export SECRET_KEY={{ RANDOM_STRING_HERE }}
export OKTA_ORG_URL={{ OKTA_ORG_URL }}
export OKTA_AUTH_TOKEN={{ OKTA_AUTH_TOKEN }}
Set the ``SECRET_KEY`` variable to a long, random string. This will be used to
secure your sessions (cookies). Then set the other two Okta variables
appropriately.

Next, run the web server.

.. code-block:: console
flask run
Finally, go visit http://localhost:5000 and explore the site!
159 changes: 149 additions & 10 deletions dashboards/solarplus-ui/app.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,157 @@
from flask import Flask, request, send_from_directory
import config
from flask import make_response, request, current_app
from flask import jsonify, redirect, url_for
from flask import g, render_template, url_for, session

from datetime import timedelta
from functools import update_wrapper
import pandas as pd
import datetime
from flask_oidc import OpenIDConnect
from okta import UsersClient

app = Flask(__name__)
app.debug = True
app.config["DEBUG"] = True
app.config["TEMPLATES_AUTO_RELOAD"] = True
app.config["OIDC_CLIENT_SECRETS"] = "client_secrets.json"
app.config["OIDC_COOKIE_SECURE"] = False
app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback"
app.config["OIDC_SCOPES"] = ["openid", "email", "profile"]
app.config["SECRET_KEY"] = config.secret_key
app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token"
oidc = OpenIDConnect(app)
okta_client = UsersClient(config.org_url, config.token)



@app.before_request
def before_request():
"""
Load a proper user object using the user ID from the ID token. This way, the
`g.user` object can be used at any point.
"""
if oidc.user_loggedin:
g.user = okta_client.get_user(oidc.user_getfield("sub"))
else:
g.user = None



@app.route("/")
def landing():
"""
Render the landing page.
"""
return render_template('landing.html')

@app.route("/index")
@oidc.require_login
def index():
"""
Render the homepage.
"""
return render_template('index.html')

@app.route("/dashboard")
@oidc.require_login
def dashboard():
"""
Render the dashboard page.
"""
return render_template("dashboard.html")

@app.route("/setpoints")
@oidc.require_login
def setpoints():
"""
Render the setpoints page.
"""
return render_template("setpoints.html")

@app.route("/weather")
@oidc.require_login
def weather():
"""
Render the weather page.
"""
return render_template("weather.html")

@app.route("/DR")
@oidc.require_login
def dr():
"""
Render the DR page.
"""
return render_template("DR.html")

@app.route("/intelligence")
@oidc.require_login
def intelligence():
"""
Render the intelligence page.
"""
return render_template("intelligence.html")


@app.route("/login")
@oidc.require_login
def login():
"""
Force the user to login, then redirect them to the dashboard.
"""
return redirect(url_for(".index"))

@app.route("/logout")
def logout():
"""
Log the user out of their account.
"""

oidc.logout()
return redirect(url_for(".landing"))

# @app.before_request
# def before_request():
# """
# Load a proper user object using the user ID from the ID token. This way, the
# `g.user` object can be used at any point.
# """
# if oidc.user_loggedin:
# g.user = okta_client.get_user(oidc.user_getfield("sub"))
# else:
# g.user = None


# @app.route('/')
# def root():
# return render_template('index.html')



# @app.route("/login")
# @oidc.require_login
# def login():
# """
# Force the user to login, then redirect them to the dashboard.
# """
# return render_template('dashboard.html')

# @app.route('/<path:path>')
# @oidc.require_login
# def static_proxy(path):
# return render_template(path)

# @app.route("/logout")
# @oidc.require_login
# def logout():
# """
# Log the user out of their account.
# """

# oidc.logout()
# return redirect(url_for(".root"))


# Flask boilerplate,
# configure CORS to make HTTP requests from javascript
Expand Down Expand Up @@ -52,13 +196,6 @@ def wrapped_function(*args, **kwargs):
return update_wrapper(wrapped_function, f)
return decorator

@app.route('/')
def root():
return app.send_static_file('login.html')

@app.route('/<path:path>')
def static_proxy(path):
return app.send_static_file(path)

@app.route('/cieeData')
@crossdomain(origin="*")
Expand Down Expand Up @@ -176,5 +313,7 @@ def extractData_anyFile(filename, startDate, endDate):
return dataInRange.to_json(orient = 'records')
'''

if __name__ == '__main__':
app.run()
# if __name__ == '__main__':
# app.run()
# debug=True
# TEMPLATES_AUTO_RELOAD=True
48 changes: 48 additions & 0 deletions dashboards/solarplus-ui/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
Packaging information and tools.
"""


from os.path import abspath, dirname, join, normpath

from setuptools import find_packages, setup


setup(
# Basic package information:
name="okta-flask-example",
version="1.0.0",
packages=find_packages(),
# Packaging options:
zip_safe=False,
include_package_data=True,
# Package dependencies:
install_requires=["Flask>=1.0.0", "flask-oidc>=1.4.0", "okta==0.0.4"],
# Metadata for PyPI:
author="Randall Degges",
author_email="[email protected]",
license="UNLICENSE",
url="https://github.com/rdegges/okta-flask-example",
keywords="python security authentication user login registration flask web okta openid connect",
description="A simple Flask app with user registration and login.",
long_description=open(
normpath(join(dirname(abspath(__file__)), "README.rst"))
).read(),
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: Public Domain",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Internet",
],
)
Loading

0 comments on commit a270453

Please sign in to comment.