Skip to content

Commit 9ac095e

Browse files
chore: formatting
ci (pyproject.toml): enable preview rules Exposed more static analysis from ruff in editor chore (auth.py): formatting
1 parent 3aa8c65 commit 9ac095e

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

app/core/auth.py

+10
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
auto_error=False
3939
)
4040

41+
4142
class CookieOrHeaderToken(SecurityBase):
4243
def __init__(
4344
self,
@@ -73,21 +74,26 @@ async def __call__(self, request: Request) -> str | None:
7374

7475
return token
7576

77+
7678
# Security schemes
7779
security = CookieOrHeaderToken(auto_error=False) # Don't auto-error so we can try form auth
7880
oauth_form_dependency = Depends(OAuth2PasswordRequestForm)
7981

82+
8083
class IPConfig(BaseModel):
8184
whitelist: list[str] = ["localhost", "127.0.0.1"]
8285
public_ips: list[str] = [] # TODO: add whitelisted public IPs here
8386

87+
8488
ip_config = IPConfig()
8589

90+
8691
def is_ip_allowed(request: Request):
8792
"""Check if the client IP is in the whitelist"""
8893
client_host = request.client.host
8994
return client_host in ip_config.whitelist or client_host in ip_config.public_ips
9095

96+
9197
async def get_current_user(
9298
request: Request,
9399
token: str | None = Depends(security),
@@ -120,18 +126,21 @@ async def get_current_user(
120126

121127
return user
122128

129+
123130
async def get_current_active_user(current_user: User = Depends(get_current_user)):
124131
"""Get current active user"""
125132
if current_user.disabled:
126133
raise HTTPException(status_code=400, detail="Inactive user")
127134
return current_user
128135

136+
129137
async def ip_whitelist_or_auth(request: Request, current_user: User = Depends(get_current_active_user)):
130138
"""Check if request is from whitelisted IP or authenticated user"""
131139
if is_ip_allowed(request):
132140
return {"bypass_auth": True}
133141
return current_user
134142

143+
135144
def check_auth(auth: dict | User) -> None:
136145
"""
137146
Shared function to check authentication result.
@@ -142,6 +151,7 @@ def check_auth(auth: dict | User) -> None:
142151
elif not isinstance(auth, User):
143152
raise HTTPException(status_code=401, detail="Unauthorized")
144153

154+
145155
# Dependencies
146156
current_user_dependency = Depends(get_current_user)
147157
current_active_user_dependency = Depends(get_current_active_user)

app/core/db.py

+13
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
# Initialize database
2222
db = Database()
2323

24+
2425
# User model
2526
class UserInfo(db.Entity):
2627
username = Required(str, unique=True)
2728
hashed_password = Required(str)
2829
email = Optional(str)
2930

31+
3032
# Initialize database connection
3133
def init_db():
3234
db.bind(provider='postgres',
@@ -44,33 +46,41 @@ def init_db():
4446
hashed_password = pwd_context.hash(DB_PASS)
4547
UserInfo(username=DB_USER, hashed_password=hashed_password)
4648

49+
4750
# Authentication models
4851
class Token(BaseModel):
4952
access_token: str
5053
token_type: str
5154

55+
5256
class TokenData(BaseModel):
5357
username: str | None = None
5458

59+
5560
class User(BaseModel):
5661
username: str
5762
email: str | None = None
5863
disabled: bool | None = None
5964

65+
6066
class UserInDB(User):
6167
hashed_password: str
6268

69+
6370
# Password handling
6471
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
6572

73+
6674
def verify_password(plain_password, hashed_password):
6775
"""Validate plaintext password against hashed password"""
6876
return pwd_context.verify(plain_password, hashed_password)
6977

78+
7079
def get_password_hash(password):
7180
"""Return hashed password"""
7281
return pwd_context.hash(password)
7382

83+
7484
# User management
7585
def get_user(username: str):
7686
"""Get user from database"""
@@ -79,6 +89,7 @@ def get_user(username: str):
7989
if user:
8090
return UserInDB(username=user.username, hashed_password=user.hashed_password)
8191

92+
8293
def authenticate_user(username: str, password: str):
8394
"""Authenticate user"""
8495
user = get_user(username)
@@ -88,6 +99,7 @@ def authenticate_user(username: str, password: str):
8899
return False
89100
return user
90101

102+
91103
def load_user(username: str):
92104
"""Load user from database"""
93105
with db_session:
@@ -97,6 +109,7 @@ def load_user(username: str):
97109
else:
98110
raise HTTPException(status_code=404, detail="User not found")
99111

112+
100113
# Token management
101114
def create_access_token(data: dict, expires_delta: timedelta | None = None):
102115
"""Create access token"""

app/core/slackbot.py

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
# strip double quotes from env strings (local image)
3333
CHANNEL = CHANNEL.strip('"')
3434

35+
3536
def load_channels():
3637
# read channel
3738
chan = pd.read_csv('channels.csv', header=0)
@@ -64,6 +65,7 @@ def load_channels():
6465

6566
return channels
6667

68+
6769
# python sdk
6870
client = WebClient(token=BOT_USER_TOKEN)
6971

app/main.py

+11
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"clientId": "meetup_bot",
103103
}
104104

105+
105106
@app.post("/token", response_model=Token)
106107
async def login_for_oauth_token(response: Response, form_data: OAuth2PasswordRequestForm = oauth_form_dependency):
107108
"""Login for oauth access token"""
@@ -130,16 +131,19 @@ async def login_for_oauth_token(response: Response, form_data: OAuth2PasswordReq
130131

131132
return {"access_token": oauth_token, "token_type": "bearer"}
132133

134+
133135
@app.get("/healthz", status_code=200)
134136
def health_check():
135137
"""Smoke test to check if the app is running"""
136138
return {"status": "ok"}
137139

140+
138141
@app.get("/", response_class=HTMLResponse)
139142
def index(request: Request):
140143
with open(Path("resources/templates/login.html")) as f:
141144
return HTMLResponse(content=f.read(), status_code=200)
142145

146+
143147
@app.post("/auth/login")
144148
def login(request: Request, username: str = Form(...), password: str = Form(...)):
145149
"""Redirect to "/docs" from index page if user successfully logs in with HTML form"""
@@ -169,6 +173,7 @@ def login(request: Request, username: str = Form(...), password: str = Form(...)
169173
detail="Incorrect username or password"
170174
)
171175

176+
172177
@api_router.get("/token")
173178
def generate_token(current_user: User = current_active_user_dependency):
174179
"""
@@ -195,6 +200,7 @@ def generate_token(current_user: User = current_active_user_dependency):
195200

196201
return access_token, refresh_token
197202

203+
198204
@api_router.get("/events")
199205
def get_events(auth: dict = ip_whitelist_auth_dependency,
200206
location: str = "Oklahoma City",
@@ -225,6 +231,7 @@ def get_events(auth: dict = ip_whitelist_auth_dependency,
225231

226232
return events
227233

234+
228235
@api_router.get("/check-schedule")
229236
def should_post_to_slack(auth: dict = ip_whitelist_auth_dependency, request: Request = None):
230237
"""
@@ -267,6 +274,7 @@ def should_post_to_slack(auth: dict = ip_whitelist_auth_dependency, request: Req
267274
"should_post": False,
268275
}
269276

277+
270278
@api_router.post("/slack")
271279
def post_slack(
272280
auth: dict = ip_whitelist_auth_dependency,
@@ -321,6 +329,7 @@ def post_slack(
321329
except Exception as e:
322330
return {"message": f"Error posting to Slack: {str(e)}", "status": "error"}
323331

332+
324333
@api_router.post("/snooze")
325334
def snooze_slack_post(
326335
duration: str,
@@ -350,6 +359,7 @@ def snooze_slack_post(
350359
except ValueError as e:
351360
raise HTTPException(status_code=400, detail=str(e)) from e
352361

362+
353363
@api_router.get("/schedule")
354364
def get_current_schedule(auth: dict | User = ip_whitelist_auth_dependency):
355365
"""
@@ -375,6 +385,7 @@ def get_current_schedule(auth: dict | User = ip_whitelist_auth_dependency):
375385

376386
return {"schedules": schedules}
377387

388+
378389
# routes
379390
app.include_router(api_router)
380391

pyproject.toml

+3
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ select = [
148148
]
149149
ignore = ["D203", "E203", "E251", "E266", "E401", "E402", "E501", "F401", "F403", "F405"]
150150

151+
# enable preview style formatting
152+
preview = true
153+
151154
# Allow unused variables when underscore-prefixed.
152155
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
153156

0 commit comments

Comments
 (0)