Use crsf token in forms, fix missing div
Use lxml for parsing the form to obtain csrf for testing
This commit is contained in:
Родитель
1b52c50740
Коммит
9b91e4c449
|
@ -16,6 +16,7 @@ from airflow import configuration
|
|||
|
||||
csrf = CsrfProtect()
|
||||
|
||||
|
||||
def create_app(config=None):
|
||||
app = Flask(__name__)
|
||||
app.secret_key = configuration.get('webserver', 'SECRET_KEY')
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
Run:<input type="hidden" value="{{ dag.dag_id }}" name="dag_id">
|
||||
{{ form.execution_date(class_="form-control") | safe }}
|
||||
<input type="submit" value="Go" class="btn btn-default" action="" method="get">
|
||||
<input name="_csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
</div>
|
||||
</form>
|
||||
<div id="container"></div>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
{{ form.arrange(class_="form-control") | safe }}
|
||||
<input type="hidden" name="root" value="{{ root }}">
|
||||
<input type="hidden" value="{{ dag.dag_id }}" name="dag_id">
|
||||
<input name="_csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
<input type="submit" value="Go" class="btn btn-default"
|
||||
action="" method="get">
|
||||
</form>
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
<div class="account-wall">
|
||||
<img src="{{ url_for("static", filename="pin_100.png") }}" />
|
||||
<form class="form-signin" method="post" action="{{ url_for('airflow.login') }}">
|
||||
{{ form.csrf_token }}
|
||||
<input type="text" class="form-control" placeholder="Username" name="username" required autofocus>
|
||||
<input type="password" class="form-control" placeholder="Password" name="password" required>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">
|
||||
|
@ -20,6 +19,7 @@
|
|||
<input type="checkbox" value="remember-me">
|
||||
Remember me
|
||||
</label>
|
||||
<input name="_csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,13 +14,15 @@
|
|||
<h2>Ad Hoc Query</h2>
|
||||
<form method="get" id="query_form">
|
||||
<div class="form-inline">
|
||||
{{ form.conn_id }}
|
||||
<input type="submit" class="btn btn-default" value="Run!">
|
||||
<input type="button" class="btn btn-default" value=".csv" id="csv">
|
||||
<span id="results"></span><br>
|
||||
<div id='ace_container'>
|
||||
{{ form.sql(rows=10) }}
|
||||
</div>
|
||||
<input name="_csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
{{ form.conn_id }}
|
||||
<input type="submit" class="btn btn-default" value="Run!">
|
||||
<input type="button" class="btn btn-default" value=".csv" id="csv">
|
||||
<span id="results"></span><br>
|
||||
<div id='ace_container'>
|
||||
{{ form.sql(rows=10) }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{ results|safe }}
|
||||
{% endblock %}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
{{ super() }}
|
||||
<h4>
|
||||
<form method="get" id="daform">
|
||||
<input name="_csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
<div class="form-inline">
|
||||
<span style='color:#AAA;'>Task Instance: </span>
|
||||
<span>
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<input type="hidden" value="{{ dag.dag_id }}" name="dag_id">
|
||||
<input type="submit" value="Go" class="btn btn-default"
|
||||
action="" method="get">
|
||||
<input name="_csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
</form>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
|
|
|
@ -45,4 +45,5 @@ mysqlclient
|
|||
unicodecsv
|
||||
slackclient
|
||||
ldap3
|
||||
Flask-WTF
|
||||
Flask-WTF
|
||||
lxml
|
1
setup.py
1
setup.py
|
@ -52,6 +52,7 @@ slack = ['slackclient>=0.15']
|
|||
statsd = ['statsd>=3.0.1, <4.0']
|
||||
vertica = ['vertica-python>=0.5.1']
|
||||
ldap = ['ldap3>=0.9.9.1']
|
||||
devel = ['lxml>=3.3.4']
|
||||
|
||||
all_dbs = postgres + mysql + hive + mssql + hdfs + vertica
|
||||
devel = all_dbs + doc + samba + s3 + ['nose'] + slack + crypto + oracle
|
||||
|
|
|
@ -9,6 +9,7 @@ from airflow import jobs, models, DAG, utils, operators, hooks, macros
|
|||
from airflow.bin import cli
|
||||
from airflow.www import app as application
|
||||
from airflow.settings import Session
|
||||
from lxml import html
|
||||
|
||||
NUM_EXAMPLE_DAGS = 7
|
||||
DEV_NULL = '/dev/null'
|
||||
|
@ -471,10 +472,22 @@ class WebLdapAuthTest(unittest.TestCase):
|
|||
app.config['TESTING'] = True
|
||||
self.app = app.test_client()
|
||||
|
||||
def get_csrf(self, response):
|
||||
tree = html.fromstring(response.data)
|
||||
form = tree.find('.//form')
|
||||
|
||||
return form.find('.//input[@name="_csrf_token"]').value
|
||||
|
||||
def login(self, username, password):
|
||||
response = self.app.get('/admin/airflow/login')
|
||||
print(response.data.decode('utf-8'))
|
||||
|
||||
csrf_token = self.get_csrf(response)
|
||||
|
||||
return self.app.post('/admin/airflow/login', data=dict(
|
||||
username=username,
|
||||
password=password
|
||||
password=password,
|
||||
csrf_token=csrf_token
|
||||
), follow_redirects=True)
|
||||
|
||||
def logout(self):
|
||||
|
@ -484,15 +497,19 @@ class WebLdapAuthTest(unittest.TestCase):
|
|||
assert configuration.getboolean('webserver', 'authenticate') is True
|
||||
|
||||
response = self.login('user1', 'userx')
|
||||
print(response.data.decode('utf-8'))
|
||||
assert 'Incorrect login details' in response.data.decode('utf-8')
|
||||
|
||||
response = self.login('userz', 'user1')
|
||||
print(response.data.decode('utf-8'))
|
||||
assert 'Incorrect login details' in response.data.decode('utf-8')
|
||||
|
||||
response = self.login('user1', 'user1')
|
||||
print(response.data.decode('utf-8'))
|
||||
assert 'Data Profiling' in response.data.decode('utf-8')
|
||||
|
||||
response = self.logout()
|
||||
print(response.data.decode('utf-8'))
|
||||
assert 'form-signin' in response.data.decode('utf-8')
|
||||
|
||||
def test_unauthorized(self):
|
||||
|
|
Загрузка…
Ссылка в новой задаче