Skip to content

Commit

Permalink
Render form with CSRF token & protect
Browse files Browse the repository at this point in the history
  • Loading branch information
Sumukh committed Aug 25, 2016
1 parent 13f4d47 commit 8fd41ed
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 7 deletions.
13 changes: 7 additions & 6 deletions server/controllers/oauth.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import datetime as dt
import logging

from flask import (abort, Blueprint, current_app, flash, redirect,
render_template, request, session, url_for, jsonify)
from flask import (Blueprint, flash, redirect, render_template,
request, session, url_for, jsonify)

from flask_login import login_required, current_user, login_user
from flask_oauthlib.contrib.oauth2 import bind_sqlalchemy
from flask_login import login_required, current_user

from server import utils
from server.models import db, User, Enrollment, Client, Token, Grant
from server.models import db, Client, Token, Grant
from server.extensions import csrf, oauth_provider

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -80,6 +78,9 @@ def save_token(token, orequest, *args, **kwargs):
@oauth_provider.authorize_handler
@login_required
def authorize(*args, **kwargs):
# Only CSRF protect this route.
csrf.protect()

if request.method == 'GET':
client_id = kwargs.get('client_id')
client = Client.query.filter_by(client_id=client_id).first()
Expand Down
123 changes: 123 additions & 0 deletions server/templates/_formhelpers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{# BS3 macros from https://gist.github.com/bearz/7394681 #}

{# Renders field for bootstrap 3 standards.

Params:
field - WTForm field
kwargs - pass any arguments you want in order to put them into the html attributes.

Example usage:
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
#}
{% macro render_field(field, label_visible=true, class_='form-control') -%}
<div class="form-group {% if field.errors %}has-error{% endif %} {{ kwargs.pop('class_', '') }}">
{% if (field.type != 'HiddenField' and field.type !='CSRFTokenField') and label_visible %}
<label for="{{ field.id }}" class="control-label">{{ field.label }}</label>
{% endif %}
{% if field.description %}
<p class="help-block">{{ field.description }}</p>
{% endif %}

{{ field(class_=class_, **kwargs) }}
{% if field.errors %}
{% for e in field.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
{%- endmacro %}

{# Renders checkbox fields since they are represented differently in bootstrap
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_

Example usage:
{{ macros.render_checkbox_field(form.remember_me) }}
#}
{% macro render_checkbox_field(field) -%}
<div class="form-group {% if field.errors %}has-error{% endif %} {{ kwargs.pop('class_', '') }}">
<label for="{{ field.id }}" class="control-label">{{ field.label }}: {{ field(type='checkbox', **kwargs) }}</label>
<div class="checkbox">
</div>
{% if field.description %}
<p class="help-block">{{ field.description }}</p>
{% endif %}
</div>
{%- endmacro %}

{# Renders radio field
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_

Example usage:
{{ macros.render_radio_field(form.answers) }}
#}
{% macro render_radio_field(field) -%}
{% for value, label, _ in field.iter_choices() %}
<div class="radio">
<label>
<input type="radio" name="{{ field.id }}" id="{{ field.id }}" value="{{ value }}">{{ label }}
</label>
</div>
{% endfor %}
{%- endmacro %}


{# Renders WTForm in bootstrap way. There are two ways to call function:
- as macros: it will render all field forms using cycle to iterate over them
- as call: it will insert form fields as you specify:
e.g. {% call macros.render_form(form, action_url=url_for('login_view'), action_text='Login',
class_='login-form') %}
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
{{ macros.render_field(form.password, placeholder='Input password', type='password') }}
{{ macros.render_checkbox_field(form.remember_me, type='checkbox') }}
{% endcall %}

Params:
form - WTForm class
action_url - url where to submit this form
action_text - text of submit button
class_ - sets a class for form
#}
{% macro render_form(form, action_url='', action_text='Submit', class_='', btn_class='btn btn-default', enctype="application/x-www-form-urlencoded") -%}
<form method="POST" action="{{ action_url }}" role="form" class="{{ class_ }}" enctype="{{ enctype }}">
{{ form.hidden_tag() if form.hidden_tag }}
{% if caller %}
{{ caller() }}
{% else %}
{% for f in form %}
{% if f.type == 'BooleanField' %}
{{ render_checkbox_field(f) }}
{% elif f.type == 'RadioField' %}
{{ render_radio_field(f) }}
{% else %}
{{ render_field(f) }}
{% endif %}
{% endfor %}
{% endif %}
<button type="submit" class="{{ btn_class }}">{{ action_text }} </button>
</form>
{%- endmacro %}

{% macro render_form_partial(form, action_url='', class_='', enctype="application/x-www-form-urlencoded") -%}
<form method="POST" action="{{ action_url }}" role="form" class="{{ class_ }}" enctype="{{ enctype }}">
{{ form.hidden_tag() if form.hidden_tag }}
{% if caller %}
{{ caller() }}
{% else %}
{% for f in form %}
{% if f.type == 'BooleanField' %}
{{ render_checkbox_field(f) }}
{% elif f.type == 'RadioField' %}
{{ render_radio_field(f) }}
{% else %}
{{ render_field(f) }}
{% endif %}
{% endfor %}
{% endif %}
</form>
{%- endmacro %}
3 changes: 3 additions & 0 deletions server/templates/auth/oauthorize.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% extends "about/base.html" %}
{% import '_formhelpers.html' as forms %}

{% block title %}Authorize {{client.name }} | Ok{% endblock %}

Expand Down Expand Up @@ -33,6 +34,7 @@ <h2><a name="policy" id="policy"></a>{{client.name}} wants to access your OK Acc
</ul>

<form class="form-horizontal" action="{{ url_for('oauth.authorize') }}" method="POST">
{% call forms.render_form_partial(CSRFForm(), action_url=url_for('oauth.authorize'), class_='form-horizontal') %}
<div class="form-group">
<p class="center-block">
<input type="hidden" name="client_id" value="{{ client.client_id }}">
Expand All @@ -52,6 +54,7 @@ <h2><a name="policy" id="policy"></a>{{client.name}} wants to access your OK Acc
</div>
<p>
</div>
{% endcall %}
</form>
</div>
</div>
Expand Down
20 changes: 19 additions & 1 deletion server/templates/staff/_formhelpers.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
class_ - sets a class for form
#}
{% macro render_form(form, action_url='', action_text='Submit', class_='', btn_class='btn btn-default', enctype="application/x-www-form-urlencoded") -%}

<form method="POST" action="{{ action_url }}" role="form" class="{{ class_ }}" enctype="{{ enctype }}">
{{ form.hidden_tag() if form.hidden_tag }}
{% if caller %}
Expand All @@ -107,3 +106,22 @@
<button type="submit" class="{{ btn_class }}">{{ action_text }} </button>
</form>
{%- endmacro %}

{% macro render_form_partial(form, action_url='', class_='', btn_class='btn btn-default', enctype="application/x-www-form-urlencoded") -%}
<form method="POST" action="{{ action_url }}" role="form" class="{{ class_ }}" enctype="{{ enctype }}">
{{ form.hidden_tag() if form.hidden_tag }}
{% if caller %}
{{ caller() }}
{% else %}
{% for f in form %}
{% if f.type == 'BooleanField' %}
{{ render_checkbox_field(f) }}
{% elif f.type == 'RadioField' %}
{{ render_radio_field(f) }}
{% else %}
{{ render_field(f) }}
{% endif %}
{% endfor %}
{% endif %}
</form>
{%- endmacro %}

0 comments on commit 8fd41ed

Please sign in to comment.