mirror of
https://github.com/Sudo-JHare/FHIRVINE-Smart-Proxy.git
synced 2025-06-14 20:20:01 +00:00
138 lines
5.5 KiB
Python
138 lines
5.5 KiB
Python
import re
|
|
from flask_wtf import FlaskForm
|
|
from wtforms import StringField, TextAreaField, URLField, SubmitField, HiddenField, IntegerField, RadioField
|
|
from wtforms.validators import DataRequired, Length, Optional, URL, Regexp, ValidationError, NumberRange
|
|
|
|
def validate_uris(form, field):
|
|
uris = field.data.split()
|
|
for uri in uris:
|
|
if not uri.startswith(('http://', 'https://')):
|
|
raise ValidationError(f'Invalid URI format: "{uri}". Must start with http:// or https://.')
|
|
if ' ' in uri:
|
|
raise ValidationError(f'URI cannot contain spaces: "{uri}"')
|
|
|
|
def validate_scopes(form, field):
|
|
scopes = field.data.split()
|
|
scope_pattern = r'^[a-zA-Z0-9\/\.\*\-_]+$'
|
|
for scope in scopes:
|
|
if not re.match(scope_pattern, scope):
|
|
raise ValidationError(f'Invalid scope format: "{scope}". Allowed characters: a-z A-Z 0-9 / . * _ -')
|
|
|
|
def validate_optional_url(form, field):
|
|
if field.data and field.data.strip():
|
|
url_validator = URL(require_tld=False)
|
|
url_validator(form, field)
|
|
|
|
class RegisterAppForm(FlaskForm):
|
|
app_name = StringField(
|
|
'Application Name',
|
|
validators=[DataRequired(), Length(min=3, max=100)]
|
|
)
|
|
redirect_uris = TextAreaField(
|
|
'Redirect URIs (Space-separated)',
|
|
validators=[DataRequired(), validate_uris],
|
|
description='Enter one or more valid redirect URIs, separated by spaces.'
|
|
)
|
|
scopes = TextAreaField(
|
|
'Allowed Scopes (Space-separated)',
|
|
validators=[DataRequired(), validate_scopes],
|
|
default='openid profile launch launch/patient patient/*.read offline_access',
|
|
description='Enter the scopes this application is allowed to request, separated by spaces.'
|
|
)
|
|
logo_uri = StringField(
|
|
'Logo URI (Optional)',
|
|
validators=[Optional(strip_whitespace=True), validate_optional_url],
|
|
description='A URL pointing to an image for the application logo.'
|
|
)
|
|
contacts = TextAreaField(
|
|
'Contacts (Optional, space-separated)',
|
|
validators=[Optional(strip_whitespace=True)],
|
|
description='Contact email addresses or URLs, separated by spaces.'
|
|
)
|
|
tos_uri = StringField(
|
|
'Terms of Service URI (Optional)',
|
|
validators=[Optional(strip_whitespace=True), validate_optional_url],
|
|
description='Link to the application\'s Terms of Service.'
|
|
)
|
|
policy_uri = StringField(
|
|
'Privacy Policy URI (Optional)',
|
|
validators=[Optional(strip_whitespace=True), validate_optional_url],
|
|
description='Link to the application\'s Privacy Policy.'
|
|
)
|
|
submit = SubmitField('Register Application')
|
|
|
|
class TestClientForm(FlaskForm):
|
|
client_id = StringField(
|
|
'Client ID',
|
|
validators=[DataRequired(), Length(min=1, max=100)]
|
|
)
|
|
response_mode = RadioField(
|
|
'Response Mode',
|
|
choices=[
|
|
('inline', 'Display Response Inline'),
|
|
('redirect', 'Redirect to URL')
|
|
],
|
|
default='inline'
|
|
)
|
|
submit = SubmitField('Launch Test')
|
|
|
|
class ConsentForm(FlaskForm):
|
|
consent = HiddenField('Consent', validators=[DataRequired()])
|
|
submit_allow = SubmitField('Allow')
|
|
submit_deny = SubmitField('Deny')
|
|
|
|
class SecurityConfigForm(FlaskForm):
|
|
token_duration = IntegerField(
|
|
'Access Token Duration (seconds)',
|
|
validators=[DataRequired(), NumberRange(min=300, max=86400)],
|
|
default=3600,
|
|
description='Duration for access tokens (300 to 86400 seconds).'
|
|
)
|
|
refresh_token_duration = IntegerField(
|
|
'Refresh Token Duration (seconds)',
|
|
validators=[DataRequired(), NumberRange(min=3600, max=604800)],
|
|
default=86400,
|
|
description='Duration for refresh tokens (3600 to 604800 seconds).'
|
|
)
|
|
allowed_scopes = TextAreaField(
|
|
'Allowed Scopes (Space-separated)',
|
|
validators=[DataRequired(), validate_scopes],
|
|
default='openid profile launch launch/patient patient/*.read offline_access',
|
|
description='Scopes allowed for all applications.'
|
|
)
|
|
submit = SubmitField('Save Security Settings')
|
|
|
|
class ProxyConfigForm(FlaskForm):
|
|
fhir_server_url = URLField(
|
|
'FHIR Server URL',
|
|
validators=[DataRequired(), URL()],
|
|
description='Base URL of the upstream FHIR server.'
|
|
)
|
|
proxy_timeout = IntegerField(
|
|
'Proxy Timeout (seconds)',
|
|
validators=[DataRequired(), NumberRange(min=5, max=60)],
|
|
default=10,
|
|
description='Timeout for proxy requests (5 to 60 seconds).'
|
|
)
|
|
submit = SubmitField('Save Proxy Settings')
|
|
|
|
class EndpointConfigForm(FlaskForm):
|
|
metadata_endpoint = StringField(
|
|
'Metadata Endpoint',
|
|
validators=[DataRequired(), Length(min=1, max=255)],
|
|
default='/metadata',
|
|
description='Relative path to the FHIR server metadata endpoint (e.g., /metadata).'
|
|
)
|
|
capability_endpoint = StringField(
|
|
'Capability Statement Endpoint',
|
|
validators=[DataRequired(), Length(min=1, max=255)],
|
|
default='/metadata',
|
|
description='Relative path to the FHIR server capability statement (e.g., /metadata).'
|
|
)
|
|
resource_base_endpoint = StringField(
|
|
'Resource Base Endpoint',
|
|
validators=[DataRequired(), Length(min=1, max=255)],
|
|
default='',
|
|
description='Base path for FHIR resources (e.g., /baseR4).'
|
|
)
|
|
submit = SubmitField('Save Endpoint Settings') |