Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ flask --app server.py run
If you're going to be working on the application and want hot reloads of the server code, add the `--debug` flag.

```shell
flask --app server.py --debug run
flask --app server.py --debug run -p 5001
Copy link
Owner Author

@mrudatsprint mrudatsprint Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my mac port 5000 was in use. I'm not sure what was using the port.

A possible solution is https://developer.apple.com/forums/thread/682332

```

Visit the local webserver at `http://localhost:5000/` and sign in using the credentials:
Visit the local webserver at `http://localhost:5001/` and sign in using the credentials:

* username: [email protected]
* password: password
2 changes: 1 addition & 1 deletion complete-application/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ CLIENT_ID=e9fdb985-9173-4e01-9d73-ac2d60d1dc8e
CLIENT_SECRET=super-secret-secret-that-should-be-regenerated-for-production
ISSUER=http://localhost:9011
APP_SECRET_KEY=0386ffa9-3bff-4c75-932a-48d6a763ce77

API_KEY=this_really_should_be_a_long_random_alphanumeric_value_but_this_still_works
1 change: 1 addition & 0 deletions complete-application/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Authlib==1.2.0
Flask==2.3.2
python-dotenv==1.0.0
requests==2.31.0
fusionauth-client==1.48.0
59 changes: 58 additions & 1 deletion complete-application/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from authlib.integrations.flask_client import OAuth
from dotenv import find_dotenv, load_dotenv
from flask import Flask, redirect, render_template, session, url_for, request, make_response
from fusionauth.fusionauth_client import FusionAuthClient


ACCESS_TOKEN_COOKIE_NAME = "cb_access_token"
REFRESH_TOKEN_COOKIE_NAME = "cb_refresh_token"
Expand All @@ -32,7 +34,7 @@
)

if __name__ == "__main__":
app.run(host="0.0.0.0", port=env.get("PORT", 5000))
app.run(host="0.0.0.0", port=env.get("PORT", 5001))

def get_logout_url():
return env.get("ISSUER") + "/oauth2/logout?" + urlencode({"client_id": env.get("CLIENT_ID")},quote_via=quote_plus)
Expand Down Expand Up @@ -146,3 +148,58 @@ def make_change():
change=change,
logoutUrl=get_logout_url())
#end::makeChangeRoute[]

#
# This is the profile page.
#
#tag::profileRoute[]
@app.route("/profile", methods=['GET', 'POST'])
def profile():
access_token = request.cookies.get(ACCESS_TOKEN_COOKIE_NAME, None)
refresh_token = request.cookies.get(REFRESH_TOKEN_COOKIE_NAME, None)

if access_token is None:
return redirect(get_logout_url())

profile = {
"error": None
}

fusionauth_api_client = FusionAuthClient(env.get('API_KEY'), env.get('ISSUER'))
if session.get('user') != None:
user = session['user']
user_id = user['sub']
application_id = user['aud']

client_response = fusionauth_api_client.retrieve_registration(user_id, application_id)
if client_response.was_successful():
registration_data = client_response.success_response['registration'].get('data')
profile['registration_data'] = registration_data

if request.method == 'POST':
try:
favorite_color = request.form["favoritecolor"]
current_color = registration_data.get('favoritecolor')

if favorite_color != current_color and len(favorite_color) > 0:
registration_data['favoritecolor'] = favorite_color
patch_request = { 'registration' : {'applicationId': application_id, 'data' : registration_data }}
client_response = fusionauth_api_client.patch_registration(user_id, patch_request)
if client_response.was_successful():
profile['registration_data'] = registration_data
else:
profile['error'] = "Unable to save data"
else:
profile["error"] = "Please enter a new color"

except KeyError:
profile["error"] = "Please enter a color"

print(profile["error"])

return render_template(
"profile.html",
session=json.loads(request.cookies.get(USERINFO_COOKIE_NAME, None)),
profile=profile,
logoutUrl=get_logout_url())
#end::profileRoute[]
4 changes: 2 additions & 2 deletions complete-application/static/css/changebank.css
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ body {
border-radius: 5px;
}

.change-message {
.change-message, .profile-message {
font-size: 20px;
margin-bottom: 15px;
}
Expand All @@ -152,6 +152,6 @@ body {
margin-left: 80px;
}

.change-container {
.change-container, .profile-container {
flex: 1;
}
1 change: 1 addition & 0 deletions complete-application/templates/account.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</div>

<div id="menu-bar" class="menu-bar">
<a class="menu-link inactive" href="/profile">Profile</a>
<a class="menu-link inactive" href="/make-change">Make Change</a>
<a class="menu-link" href="/account">Account</a>
</div>
Expand Down
1 change: 1 addition & 0 deletions complete-application/templates/make-change.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</div>

<div id="menu-bar" class="menu-bar">
<a class="menu-link inactive" href="/profile">Profile</a>
<a class="menu-link" href="/make-change">Make Change</a>
<a class="menu-link inactive" href="/account">Account</a>
</div>
Expand Down
54 changes: 54 additions & 0 deletions complete-application/templates/profile.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<html>
<head>
<meta charset="utf-8" />
<title>FusionAuth OpenID and PKCE example</title>
<link rel="stylesheet" href="/static/css/changebank.css">
</head>
<body>
<div id="page-container">
<div id="page-header">
<div id="logo-header">
<img src="https://fusionauth.io/assets/img/samplethemes/changebank/changebank.svg" />
<div class="h-row">
<p class="header-email">{{session["email"]}}</p>
<a class="button-lg" href={{logoutUrl}}>Logout</a>
</div>
</div>

<div id="menu-bar" class="menu-bar">
<a class="menu-link" href="/profile">Profile</a>
<a class="menu-link inactive" href="/make-change">Make Change</a>
<a class="menu-link inactive" href="/account">Account</a>
</div>
</div>

<div style="flex: 1;">
<div class="column-container">
<div class="app-container profile-container">
<h3>Current preferences</h3>

<form action="/profile" method="post">
{% if profile["error"] is not none: %}
<div class="error-message">{{profile.error}}</div>
{% endif %}
{% if profile["registration_data"] %}
{% set registration_data = profile["registration_data"] %}
{% for key in registration_data.keys() %}
<p>
{% if key == 'favoritecolor' and registration_data['favoritecolor'] | length > 0 %}
Favorite Color: <input name='{{key}}' value='{{registration_data['favoritecolor']}}' />
{% else %}
Favorite Color: <input name='{{key}}' value='' />
{% endif %}
</p>
{% endfor %}
{% else %}
Favorite Color: <input name='favoritecolor' value='' />
{% endif %}
<input type="submit" value="Update"></input>
</form>
</div>
</div>
</div>
</body>
</html>
38 changes: 38 additions & 0 deletions documentation/load-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Load Testing FusionAuth

Load testing FusionAuth should be performed using a realistic production configuration. The throughput goal should be to target a number of requests per second.

## Configure FusionAuth
1. Setup an API key

2. Setup a tenant

3. Setup an application

## Running a load test
1. Register users for the application

2. Login users using the [Login API ](https://fusionauth.io/docs/apis/login)

## Cleanup

Deleting the tenant will remove the application and users.

## Load Testing Tools
A tool that can make HTTP requests will work.

1. jmeter
https://jmeter.apache.org

2. gatling
https://gatling.io


## Helpful Articles

1. FusionAuth [Documentation ](https://fusionauth.io/docs/operate/secure-and-monitor/monitor#load-testing)

2. Load testing scripts from an [open source project ](https://github.com/FusionAuth/fusionauth-load-tests/)

3. FusionAuth User Registration Hits 100,000,000 In [Load Test ](https://fusionauth.io/blog/got-users-100-million)

10 changes: 5 additions & 5 deletions kickstart/kickstart.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"OPTIONS"
],
"allowedOrigins": [
"http://localhost:5000"
"http://localhost:5001"
],
"debug": false,
"enabled": true,
Expand Down Expand Up @@ -77,14 +77,14 @@
"name": "Example app",
"oauthConfiguration": {
"authorizedRedirectURLs": [
"http://localhost:5000/callback",
"http://localhost:5000"
"http://localhost:5001/callback",
"http://localhost:5001"
],
"authorizedOriginURLs": [
"http://localhost:5000"
"http://localhost:5001"
],
"clientSecret": "super-secret-secret-that-should-be-regenerated-for-production",
"logoutURL": "http://localhost:5000/logout",
"logoutURL": "http://localhost:5001/logout",
"enabledGrants": [
"authorization_code",
"refresh_token"
Expand Down