From 3713135ee8be7cbf0bc4e90459098b9f175afe8d Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Wed, 12 Jul 2023 02:51:49 -0400 Subject: [PATCH] Support for Secure Headers and Github Actions (#72) * Support for Secure Headers and Github Actions * Reformat main.py * Add working dir to python checks * Add line length to black --- .github/dependabot.yml | 10 ++++++++ .github/workflows/python-lint.yml | 30 +++++++++++++++++++++++ .gitignore | 1 + README.md | 3 ++- gdash/__main__.py | 40 +++++++++++++------------------ ruff.toml | 14 +++++++++++ 6 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/python-lint.yml create mode 100644 ruff.toml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..24950de --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "pip" + directory: "/api" + schedule: + interval: "daily" diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml new file mode 100644 index 0000000..3b1c3d6 --- /dev/null +++ b/.github/workflows/python-lint.yml @@ -0,0 +1,30 @@ +name: Python Lint + +on: + pull_request: + branches: + - main + paths-ignore: + - 'docs/**' + - 'extras/**' + - '**.md' + - '**.adoc' + +jobs: + lint-python-code: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: Run ruff check + uses: chartboost/ruff-action@v1 + with: + src: "./gdash" + args: "--verbose" + - name: Run black check + uses: psf/black@stable + with: + options: "--check --diff --verbose -l 120" + src: "./gdash" diff --git a/.gitignore b/.gitignore index 194fbe5..176dabd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ __pycache__ node_modules .DS_Store gdash/ui +**/.ruff_cache diff --git a/README.md b/README.md index 8bae172..2840f1c 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Other available options are ``` $ gdash --help usage: gdash [-h] [--version] [--port PORT] [--gluster-binary GLUSTER_BINARY] - [--auth-file AUTH_FILE] [--ssl-cert CERT_FILE] [--ssl-key KEY_FILE] [--ssl-ca CA_CERT_FILE] + [--auth-file AUTH_FILE] [--ssl-cert CERT_FILE] [--ssl-key KEY_FILE] [--ssl-ca CA_CERT_FILE] [--ssl-ciphers LIST_OF_CIPHERS] host gdash - GlusterFS Dashboard @@ -68,6 +68,7 @@ optional arguments: --ssl-cert CERT_FILE Path to SSL Certificate file --ssl-key KEY_FILE Path to SSL Key file --ssl-ca CA_FILE Path to SSL CA Certificate file + --ssl-ciphers List of SSL Ciphers to allow ``` ## Blog diff --git a/gdash/__main__.py b/gdash/__main__.py index c28b2fc..799da14 100644 --- a/gdash/__main__.py +++ b/gdash/__main__.py @@ -23,16 +23,21 @@ "/": { "tools.staticdir.on": True, "tools.sessions.on": True, - "tools.sessions.secure" = True, - "tools.sessions.httponly" = True, - "tools.secureheaders.on" = True, - "tools.staticdir.dir": os.path.join( - os.path.dirname(os.path.abspath(__file__)), "ui" - ), + "tools.sessions.secure": True, + "tools.sessions.httponly": True, + "tools.secureheaders.on": True, + "tools.staticdir.dir": os.path.join(os.path.dirname(os.path.abspath(__file__)), "ui"), }, } +def secureheaders(): + headers = cherrypy.response.headers + headers["X-Frame-Options"] = "DENY" + headers["X-XSS-Protection"] = "1; mode=block" + headers["Content-Security-Policy"] = "default-src='self'" + + def is_valid_admin_login(username, password): if USERS is None: return True @@ -162,24 +167,12 @@ def get_args(): parser.add_argument("--gluster-binary", default="gluster") parser.add_argument( "--auth-file", - help=( - "Users Credentials file. One user entry per row " - "in the format =" - ), - ) - parser.add_argument( - "--ssl-cert", default=None, help=("Path to SSL Certificate used by Gdash") + help=("Users Credentials file. One user entry per row " "in the format ="), ) - parser.add_argument( - "--ssl-key", default=None, help=("Path to SSL Key used by Gdash") - ) - parser.add_argument( - "--ssl-ca", default=None, help=("Path to SSL CA Certificate used by Gdash") - ) - parser.add_argument( - "--ssl-ciphers", default=None, help=("List of SSL Ciphers to allow") - ) - + parser.add_argument("--ssl-cert", default=None, help=("Path to SSL Certificate used by Gdash")) + parser.add_argument("--ssl-key", default=None, help=("Path to SSL Key used by Gdash")) + parser.add_argument("--ssl-ca", default=None, help=("Path to SSL CA Certificate used by Gdash")) + parser.add_argument("--ssl-ciphers", default=None, help=("List of SSL Ciphers to allow")) return parser.parse_args() @@ -217,6 +210,7 @@ def main(): cherrypy_cfg["server.ssl_module"] = "builtin" cherrypy.config.update(cherrypy_cfg) + cherrypy.tools.secureheaders = cherrypy.Tool("before_finalize", secureheaders, priority=60) webapp = GdashWeb() webapp.api = GdashApis() cherrypy.quickstart(webapp, "/", conf) diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..00fc9bc --- /dev/null +++ b/ruff.toml @@ -0,0 +1,14 @@ +# Enable flake8-bugbear (`B`) rules. +select = ["E", "F", "B"] + +# Never enforce `E501` (line length violations). +ignore = ["E501"] + +# Avoid trying to fix flake8-bugbear (`B`) violations. +unfixable = ["B"] + +# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`. +[per-file-ignores] +"__init__.py" = ["E402"] +"path/to/file.py" = ["E402"] +