Skip to content

Commit 123ad20

Browse files
committed
run lint & format, add ci pipeline
1 parent 28d0088 commit 123ad20

File tree

222 files changed

+3691
-3474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

222 files changed

+3691
-3474
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
1-
name: ci.yml
1+
name: CI
22
on:
33
push:
4-
branches: [ main ]
4+
branches: [ main, ci-test ]
55

66
jobs:
77
check:
8-
9-
test:
10-
8+
name: Lint & format (ruff)
9+
runs-on: ubuntu-22.04
10+
steps:
11+
- uses: actions/checkout@v6
12+
- name: Install uv
13+
uses: astral-sh/setup-uv@v7
14+
- name: Sync dev dependencies
15+
run: uv sync --frozen --dev
16+
- name: Ruff check
17+
run: uv run ruff check .
18+
- name: Ruff format check
19+
run: uv run ruff format --check .
20+
- name: mypy check
21+
run: uv run mypy lemur

lemur/__init__.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
.. moduleauthor:: Hossein Shafagh <[email protected]>
1010
1111
"""
12+
1213
import socket
1314
import time
1415
import urllib.parse
@@ -78,9 +79,7 @@
7879

7980

8081
def create_app(config_path=None):
81-
app = factory.create_app(
82-
app_name=__name__, blueprints=LEMUR_BLUEPRINTS, config=config_path
83-
)
82+
app = factory.create_app(app_name=__name__, blueprints=LEMUR_BLUEPRINTS, config=config_path)
8483
configure_hook(app)
8584
return app
8685

@@ -140,29 +139,32 @@ def sanitize_path(*, path: str) -> str:
140139
parsed_path.path,
141140
parsed_path.params,
142141
"<sanitized_query_parameters>",
143-
parsed_path.fragment
142+
parsed_path.fragment,
144143
)
145144
)
146145
return path
147146

148147
# Log request headers
149148
skip_endpoints = any(
150-
endpoint in request.full_path for endpoint in app.config.get("LOG_REQUEST_HEADERS_SKIP_ENDPOINT", [])
149+
endpoint in request.full_path
150+
for endpoint in app.config.get("LOG_REQUEST_HEADERS_SKIP_ENDPOINT", [])
151151
)
152152
if app.config.get("LOG_REQUEST_HEADERS", False) and not skip_endpoints:
153-
app.logger.info({
154-
"lemur": socket.gethostname(),
155-
"ingress-ip": request.remote_addr,
156-
"request-id": request.headers.get("X-Request-Id"),
157-
"ip": request.headers.get("X-Real-Ip", request.remote_addr),
158-
"method": request.method,
159-
"scheme": request.headers.get("X-Scheme", request.scheme),
160-
"path": sanitize_path(path=request.full_path),
161-
"status": response.status_code,
162-
"user-agent": request.headers.get("User-Agent"),
163-
"referer": sanitize_path(path=request.headers.get("Referer")),
164-
"host": request.headers.get("Host")
165-
})
153+
app.logger.info(
154+
{
155+
"lemur": socket.gethostname(),
156+
"ingress-ip": request.remote_addr,
157+
"request-id": request.headers.get("X-Request-Id"),
158+
"ip": request.headers.get("X-Real-Ip", request.remote_addr),
159+
"method": request.method,
160+
"scheme": request.headers.get("X-Scheme", request.scheme),
161+
"path": sanitize_path(path=request.full_path),
162+
"status": response.status_code,
163+
"user-agent": request.headers.get("User-Agent"),
164+
"referer": sanitize_path(path=request.headers.get("Referer")),
165+
"host": request.headers.get("Host"),
166+
}
167+
)
166168

167169
# Update custom response headers
168170
response.headers.update(custom_response_headers)

lemur/acme_providers/cli.py

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,10 @@ def cli():
2626
"--domain",
2727
"domain",
2828
required=True,
29-
help="Name of the Domain to store to (ex. \"_acme-chall.test.com\"."
29+
help='Name of the Domain to store to (ex. "_acme-chall.test.com".',
3030
)
3131
@click.option(
32-
"-t",
33-
"--token",
34-
"token",
35-
required=True,
36-
help="Value of the Token to store in DNS as content."
32+
"-t", "--token", "token", required=True, help="Value of the Token to store in DNS as content."
3733
)
3834
def dnstest_command(domain, token):
3935
dnstest(domain, token)
@@ -105,31 +101,18 @@ def dnstest(domain, token):
105101
"token",
106102
default="date: " + arrow.utcnow().format("YYYY-MM-DDTHH-mm-ss"),
107103
required=False,
108-
help="Value of the Token to store in DNS as content."
104+
help="Value of the Token to store in DNS as content.",
109105
)
110106
@click.option(
111107
"-n",
112108
"--token_name",
113109
"token_name",
114110
default="Token-" + arrow.utcnow().format("YYYY-MM-DDTHH-mm-ss"),
115111
required=False,
116-
help="path"
117-
)
118-
@click.option(
119-
"-p",
120-
"--prefix",
121-
"prefix",
122-
default="test/",
123-
required=False,
124-
help="S3 bucket prefix"
125-
)
126-
@click.option(
127-
"-a",
128-
"--account_number",
129-
"account_number",
130-
required=True,
131-
help="AWS Account"
112+
help="path",
132113
)
114+
@click.option("-p", "--prefix", "prefix", default="test/", required=False, help="S3 bucket prefix")
115+
@click.option("-a", "--account_number", "account_number", required=True, help="AWS Account")
133116
@click.option(
134117
"-b",
135118
"--bucket_name",
@@ -201,5 +184,5 @@ def upload_acme_token_s3(token, token_name, prefix, account_number, bucket_name)
201184
prefix + "/"
202185

203186
token_res = s3.get(bucket_name, prefix + token_name, account_number=account_number)
204-
assert (token_res == token)
187+
assert token_res == token
205188
s3.delete(bucket_name, prefix + token_name, account_number=account_number)

lemur/api_keys/cli.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:license: Apache, see LICENSE for more details.
66
.. moduleauthor:: Eric Coan <[email protected]>
77
"""
8+
89
from datetime import datetime
910

1011
import click
@@ -21,13 +22,9 @@ def cli():
2122

2223

2324
@cli.command("create")
24-
@click.option(
25-
"-u", "--user-id", "uid", help="The User ID this access key belongs too."
26-
)
25+
@click.option("-u", "--user-id", "uid", help="The User ID this access key belongs too.")
2726
@click.option("-n", "--name", "name", help="The name of this API Key.")
28-
@click.option(
29-
"-t", "--ttl", "ttl", help="The TTL of this API Key. -1 for forever."
30-
)
27+
@click.option("-t", "--ttl", "ttl", help="The TTL of this API Key. -1 for forever.")
3128
def create_command(uid, name, ttl):
3229
create(uid, name, ttl)
3330

lemur/api_keys/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
:license: Apache, see LICENSE for more details.
77
.. moduleauthor:: Eric Coan <[email protected]>
88
"""
9+
910
from sqlalchemy import BigInteger, Boolean, Column, ForeignKey, Integer, String
1011

1112
from lemur.database import BaseModel

lemur/api_keys/schemas.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:license: Apache, see LICENSE for more details.
66
.. moduleauthor:: Eric Coan <[email protected]>
77
"""
8+
89
from flask import g
910
from marshmallow import fields
1011

@@ -22,9 +23,7 @@ def current_user_id():
2223

2324
class ApiKeyInputSchema(LemurInputSchema):
2425
name = fields.String(required=False)
25-
user = fields.Nested(
26-
UserInputSchema, missing=current_user_id, default=current_user_id
27-
)
26+
user = fields.Nested(UserInputSchema, missing=current_user_id, default=current_user_id)
2827
ttl = fields.Integer()
2928

3029

lemur/api_keys/service.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:license: Apache, see LICENSE for more details.
66
.. moduleauthor:: Eric Coan <[email protected]>
77
"""
8+
89
from lemur import database
910
from lemur.api_keys.models import ApiKey
1011
from lemur.logs import service as log_service

lemur/api_keys/views.py

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
.. moduleauthor:: Eric Coan <[email protected]>
88
99
"""
10+
1011
from datetime import datetime
1112

1213
from flask import Blueprint, g
@@ -33,7 +34,7 @@
3334

3435

3536
class ApiKeyList(AuthenticatedResource):
36-
""" Defines the 'api_keys' endpoint """
37+
"""Defines the 'api_keys' endpoint"""
3738

3839
def __init__(self):
3940
super().__init__()
@@ -148,13 +149,11 @@ def post(self, data=None):
148149
revoked=False,
149150
issued_at=int(datetime.utcnow().timestamp()),
150151
)
151-
return dict(
152-
jwt=create_token(access_token.user_id, access_token.id, access_token.ttl)
153-
)
152+
return dict(jwt=create_token(access_token.user_id, access_token.id, access_token.ttl))
154153

155154

156155
class ApiKeyUserList(AuthenticatedResource):
157-
""" Defines the 'keys' endpoint on the 'users' endpoint. """
156+
"""Defines the 'keys' endpoint on the 'users' endpoint."""
158157

159158
def __init__(self):
160159
super().__init__()
@@ -253,11 +252,7 @@ def post(self, user_id, data=None):
253252
if not ApiKeyCreatorPermission().can():
254253
if user_id != g.current_user.id:
255254
return (
256-
dict(
257-
message="You are not authorized to create tokens for: {}".format(
258-
user_id
259-
)
260-
),
255+
dict(message="You are not authorized to create tokens for: {}".format(user_id)),
261256
403,
262257
)
263258

@@ -268,9 +263,7 @@ def post(self, user_id, data=None):
268263
revoked=False,
269264
issued_at=int(datetime.utcnow().timestamp()),
270265
)
271-
return dict(
272-
jwt=create_token(access_token.user_id, access_token.id, access_token.ttl)
273-
)
266+
return dict(jwt=create_token(access_token.user_id, access_token.id, access_token.ttl))
274267

275268

276269
class ApiKeys(AuthenticatedResource):
@@ -366,9 +359,7 @@ def put(self, aid, data=None):
366359
if not ApiKeyCreatorPermission().can():
367360
return dict(message="You are not authorized to update this token!"), 403
368361

369-
service.update(
370-
access_key, name=data["name"], revoked=data["revoked"], ttl=data["ttl"]
371-
)
362+
service.update(access_key, name=data["name"], revoked=data["revoked"], ttl=data["ttl"])
372363
return dict(jwt=create_token(access_key.user_id, access_key.id, access_key.ttl))
373364

374365
def delete(self, aid):
@@ -512,9 +503,7 @@ def put(self, uid, aid, data=None):
512503
if access_key.user_id != uid:
513504
return dict(message="You are not authorized to update this token!"), 403
514505

515-
service.update(
516-
access_key, name=data["name"], revoked=data["revoked"], ttl=data["ttl"]
517-
)
506+
service.update(access_key, name=data["name"], revoked=data["revoked"], ttl=data["ttl"])
518507
return dict(jwt=create_token(access_key.user_id, access_key.id, access_key.ttl))
519508

520509
def delete(self, uid, aid):
@@ -616,10 +605,6 @@ def get(self, aid):
616605

617606
api.add_resource(ApiKeyList, "/keys", endpoint="api_keys")
618607
api.add_resource(ApiKeys, "/keys/<int:aid>", endpoint="api_key")
619-
api.add_resource(
620-
ApiKeysDescribed, "/keys/<int:aid>/described", endpoint="api_key_described"
621-
)
608+
api.add_resource(ApiKeysDescribed, "/keys/<int:aid>/described", endpoint="api_key_described")
622609
api.add_resource(ApiKeyUserList, "/users/<int:user_id>/keys", endpoint="user_api_keys")
623-
api.add_resource(
624-
UserApiKeys, "/users/<int:uid>/keys/<int:aid>", endpoint="user_api_key"
625-
)
610+
api.add_resource(UserApiKeys, "/users/<int:uid>/keys/<int:aid>", endpoint="user_api_key")

lemur/auth/ldap.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:license: Apache, see LICENSE for more details.
66
.. moduleauthor:: Ian Stahnke <[email protected]>
77
"""
8+
89
import ldap
910
from flask import current_app
1011

@@ -44,9 +45,7 @@ def __init__(self, args):
4445
self.ldap_default_role = current_app.config.get("LEMUR_DEFAULT_ROLE", None)
4546
self.ldap_required_group = current_app.config.get("LDAP_REQUIRED_GROUP", None)
4647
self.ldap_groups_to_roles = current_app.config.get("LDAP_GROUPS_TO_ROLES", None)
47-
self.ldap_is_active_directory = current_app.config.get(
48-
"LDAP_IS_ACTIVE_DIRECTORY", False
49-
)
48+
self.ldap_is_active_directory = current_app.config.get("LDAP_IS_ACTIVE_DIRECTORY", False)
5049
self.ldap_attrs = ["memberOf"]
5150
self.ldap_client = None
5251
self.ldap_groups = None
@@ -110,9 +109,7 @@ def _authorize(self):
110109
# update their 'roles'
111110
role = role_service.get_by_name(self.ldap_principal)
112111
if not role:
113-
description = "auto generated role based on owner: {}".format(
114-
self.ldap_principal
115-
)
112+
description = "auto generated role based on owner: {}".format(self.ldap_principal)
116113
role = role_service.create(
117114
self.ldap_principal, description=description, third_party=True
118115
)
@@ -127,14 +124,10 @@ def _authorize(self):
127124
if role:
128125
if ldap_group_name in self.ldap_groups:
129126
current_app.logger.debug(
130-
"assigning role {} to ldap user {}".format(
131-
self.ldap_principal, role
132-
)
127+
"assigning role {} to ldap user {}".format(self.ldap_principal, role)
133128
)
134129
if not role.third_party:
135-
role = role_service.set_third_party(
136-
role.id, third_party_status=True
137-
)
130+
role = role_service.set_third_party(role.id, third_party_status=True)
138131
roles.add(role)
139132
return roles
140133

@@ -176,9 +169,7 @@ def _bind(self):
176169
self.ldap_client.set_option(ldap.OPT_X_TLS_DEMAND, True)
177170
self.ldap_client.set_option(ldap.OPT_DEBUG_LEVEL, 255)
178171
if self.ldap_cacert_file:
179-
self.ldap_client.set_option(
180-
ldap.OPT_X_TLS_CACERTFILE, self.ldap_cacert_file
181-
)
172+
self.ldap_client.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ldap_cacert_file)
182173
self.ldap_client.simple_bind_s(self.ldap_principal, self.ldap_password)
183174
except ldap.INVALID_CREDENTIALS:
184175
self.ldap_client.unbind()

lemur/auth/permissions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
:license: Apache, see LICENSE for more details.
77
.. moduleauthor:: Kevin Glisson <[email protected]>
88
"""
9+
910
from functools import partial
1011
from collections import namedtuple
1112

0 commit comments

Comments
 (0)