Repository: incubator-airflow Updated Branches: refs/heads/master a5e57dc4a -> f1d72e53b
[AIRFLOW-1321] Fix hidden field key to ignore case Webserver has a feature to hide sensitive variable fields, which key contain specific words. But its matching is case-sensitive, so "google_api_key" is hidden but "GOOGLE_API_KEY" is not. This behaviour is not intuitive, so this PR fixes it to be case-insensitive. Project: http://git-wip-us.apache.org/repos/asf/incubator-airflow/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-airflow/commit/46204606 Tree: http://git-wip-us.apache.org/repos/asf/incubator-airflow/tree/46204606 Diff: http://git-wip-us.apache.org/repos/asf/incubator-airflow/diff/46204606 Branch: refs/heads/master Commit: 46204606e3655a4b0785c1bca19a51b9a451a2eb Parents: e870a8e Author: Kengo Seki <[email protected]> Authored: Mon Jun 26 14:28:07 2017 +0900 Committer: Kengo Seki <[email protected]> Committed: Mon Jun 26 20:36:01 2017 -0400 ---------------------------------------------------------------------- airflow/config_templates/default_test.cfg | 3 +++ airflow/www/utils.py | 14 ++++++++++ airflow/www/views.py | 20 ++------------ tests/www/test_utils.py | 36 ++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/46204606/airflow/config_templates/default_test.cfg ---------------------------------------------------------------------- diff --git a/airflow/config_templates/default_test.cfg b/airflow/config_templates/default_test.cfg index 1c0d34c..1fd1cce 100644 --- a/airflow/config_templates/default_test.cfg +++ b/airflow/config_templates/default_test.cfg @@ -87,3 +87,6 @@ max_threads = 2 catchup_by_default = True scheduler_zombie_task_threshold = 300 dag_dir_list_interval = 0 + +[admin] +hide_sensitive_variable_fields = True http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/46204606/airflow/www/utils.py ---------------------------------------------------------------------- diff --git a/airflow/www/utils.py b/airflow/www/utils.py index d2218de..0846542 100644 --- a/airflow/www/utils.py +++ b/airflow/www/utils.py @@ -35,6 +35,20 @@ from airflow.utils.json import AirflowJsonEncoder AUTHENTICATE = configuration.getboolean('webserver', 'AUTHENTICATE') +DEFAULT_SENSITIVE_VARIABLE_FIELDS = ( + 'password', + 'secret', + 'passwd', + 'authorization', + 'api_key', + 'apikey', + 'access_token', +) + +def should_hide_value_for_key(key_name): + return any(s in key_name.lower() for s in DEFAULT_SENSITIVE_VARIABLE_FIELDS) \ + and configuration.getboolean('admin', 'hide_sensitive_variable_fields') + class LoginMixin(object): def is_accessible(self): http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/46204606/airflow/www/views.py ---------------------------------------------------------------------- diff --git a/airflow/www/views.py b/airflow/www/views.py index 541c3ff..6c39462 100644 --- a/airflow/www/views.py +++ b/airflow/www/views.py @@ -90,16 +90,6 @@ logout_user = airflow.login.logout_user FILTER_BY_OWNER = False -DEFAULT_SENSITIVE_VARIABLE_FIELDS = ( - 'password', - 'secret', - 'passwd', - 'authorization', - 'api_key', - 'apikey', - 'access_token', -) - if conf.getboolean('webserver', 'FILTER_BY_OWNER'): # filter_by_owner if authentication is enabled and filter_by_owner is true FILTER_BY_OWNER = not current_app.config['LOGIN_DISABLED'] @@ -281,12 +271,6 @@ def recurse_tasks(tasks, task_ids, dag_ids, task_id_to_dag): task_id_to_dag[tasks.task_id] = tasks.dag -def should_hide_value_for_key(key_name): - return any(s in key_name for s in DEFAULT_SENSITIVE_VARIABLE_FIELDS) \ - and conf.getboolean('admin', 'hide_sensitive_variable_fields') - - - def get_chart_height(dag): """ TODO(aoen): See [AIRFLOW-1263] We use the number of tasks in the DAG as a heuristic to @@ -2282,7 +2266,7 @@ class VariableView(wwwutils.DataProfilingMixin, AirflowModelView): list_template = 'airflow/variable_list.html' def hidden_field_formatter(view, context, model, name): - if should_hide_value_for_key(model.key): + if wwwutils.should_hide_value_for_key(model.key): return Markup('*' * 8) return getattr(model, name) @@ -2339,7 +2323,7 @@ class VariableView(wwwutils.DataProfilingMixin, AirflowModelView): return response def on_form_prefill(self, form, id): - if should_hide_value_for_key(form.key.data): + if wwwutils.should_hide_value_for_key(form.key.data): form.val.data = '*' * 8 http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/46204606/tests/www/test_utils.py ---------------------------------------------------------------------- diff --git a/tests/www/test_utils.py b/tests/www/test_utils.py new file mode 100644 index 0000000..bb0860f --- /dev/null +++ b/tests/www/test_utils.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from airflow.www import utils + + +class UtilsTest(unittest.TestCase): + + def setUp(self): + super(UtilsTest, self).setUp() + + def test_normal_variable_should_not_be_hidden(self): + self.assertFalse(utils.should_hide_value_for_key("key")) + + def test_sensitive_variable_should_be_hidden(self): + self.assertTrue(utils.should_hide_value_for_key("google_api_key")) + + def test_sensitive_variable_should_be_hidden_ic(self): + self.assertTrue(utils.should_hide_value_for_key("GOOGLE_API_KEY")) + + +if __name__ == '__main__': + unittest.main()
