OAuth: Add app type (is_clientside)

This commit is contained in:
rubenwardy 2023-11-07 23:06:22 +00:00
parent f74931633c
commit 9b0f84bac5
5 changed files with 52 additions and 2 deletions

@ -22,7 +22,7 @@ from flask import Blueprint, render_template, redirect, url_for, request, jsonif
from flask_babel import lazy_gettext, gettext
from flask_login import current_user, login_required
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, URLField
from wtforms import StringField, SubmitField, URLField, SelectField
from wtforms.validators import InputRequired, Length, Optional
from app import csrf
@ -167,6 +167,10 @@ class OAuthClientForm(FlaskForm):
title = StringField(lazy_gettext("Title"), [InputRequired(), Length(5, 30)])
description = StringField(lazy_gettext("Description"), [Optional()])
redirect_url = URLField(lazy_gettext("Redirect URL"), [InputRequired(), Length(5, 123)])
app_type = SelectField(lazy_gettext("App Type"), [InputRequired()], choices=[
("server", "Server-side (client_secret is kept safe)"),
("client", "Client-side (client_secret is visible to all users)"),
], coerce=lambda x: x)
submit = SubmitField(lazy_gettext("Save"))
@ -186,6 +190,7 @@ def create_edit_client(username, id_=None):
abort(404)
form = OAuthClientForm(formdata=request.form, obj=client)
if form.validate_on_submit():
if is_new:
client = OAuthClient()

@ -55,6 +55,7 @@ class Collection(db.Model):
long_description = db.Column(db.UnicodeText, nullable=True)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
private = db.Column(db.Boolean, nullable=False, default=False)
pinned = db.Column(db.Boolean, nullable=False, default=False)
packages = db.relationship("Package", secondary=CollectionPackage.__table__, backref="collections")
items = db.relationship("CollectionPackage", back_populates="collection", order_by=db.asc("order"),

@ -560,6 +560,7 @@ class OAuthClient(db.Model):
redirect_url = db.Column(db.String(128), nullable=False)
approved = db.Column(db.Boolean, nullable=False, default=False)
verified = db.Column(db.Boolean, nullable=False, default=False)
is_clientside = db.Column(db.Boolean, nullable=False, default=False)
owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
owner = db.relationship("User", foreign_keys=[owner_id], back_populates="clients")
@ -567,3 +568,11 @@ class OAuthClient(db.Model):
tokens = db.relationship("APIToken", back_populates="client", lazy="dynamic", cascade="all, delete, delete-orphan")
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
def get_app_type(self):
return "client" if self.is_clientside else "server"
def set_app_type(self, value):
self.is_clientside = value == "client"
app_type = property(get_app_type, set_app_type)

@ -47,7 +47,9 @@
<label class="form-label" for="client_secret">client_secret</label>
<input class="form-control" type="text" id="client_secret" name="client_secret" value="{{ client.secret }}" readonly>
<p class="form-text text-muted">
{{ _("Keep the secret safe") }}
{% if not client.is_clientside %}
{{ _("You must keep the secret safe. If you are unable, set the app type to 'client-side'.") }}
{% endif %}
</p>
</div>
<div class="form-group">
@ -65,6 +67,7 @@
{{ render_field(form.title) }}
{{ render_field(form.description, hint=_("Shown to users when you request access to their account")) }}
{{ render_field(form.redirect_url) }}
{{ render_field(form.app_type, hint=_("Where will you store your client_secret?")) }}
{{ render_submit_field(form.submit) }}
</form>

@ -0,0 +1,32 @@
"""empty message
Revision ID: 7828535fe339
Revises: 52cf6746f255
Create Date: 2023-11-07 22:51:39.450652
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '7828535fe339'
down_revision = '52cf6746f255'
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table('collection', schema=None) as batch_op:
batch_op.add_column(sa.Column('pinned', sa.Boolean(), nullable=False, server_default="false"))
with op.batch_alter_table('oauth_client', schema=None) as batch_op:
batch_op.add_column(sa.Column('is_clientside', sa.Boolean(), nullable=False, server_default="false"))
def downgrade():
with op.batch_alter_table('oauth_client', schema=None) as batch_op:
batch_op.drop_column('is_clientside')
with op.batch_alter_table('collection', schema=None) as batch_op:
batch_op.drop_column('pinned')