Skip to content

feat(auth): add device flow and token auth for headless/CI#75

Open
Adarsha1999 wants to merge 1 commit intoceph:mainfrom
Adarsha1999:feature/headless-api
Open

feat(auth): add device flow and token auth for headless/CI#75
Adarsha1999 wants to merge 1 commit intoceph:mainfrom
Adarsha1999:feature/headless-api

Conversation

@Adarsha1999
Copy link
Member

@Adarsha1999 Adarsha1999 commented Feb 9, 2026

Merge #51 first before this PR

Contribution Guidelines

To sign and test your commits, please refer to Contibution guidelines.

Checklist

@Adarsha1999 Adarsha1999 marked this pull request as draft February 9, 2026 09:49
@deepssin
Copy link

GH issue - #74

@Adarsha1999 Adarsha1999 marked this pull request as ready for review February 13, 2026 12:19
@Adarsha1999 Adarsha1999 requested a review from zmc February 18, 2026 17:31
"access_token": token,
}
request.session["user"] = data
from teuthology_api.services.helpers import isAdmin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we move the import statement here?

Comment on lines +60 to +74
import gevent.monkey # noqa: E402 - before teuthology
_orig_patch_all = gevent.monkey.patch_all

def _patch_all_ssl_off(**kwargs):
kwargs["ssl"] = False
return _orig_patch_all(**kwargs)

gevent.monkey.patch_all = _patch_all_ssl_off
import teuthology # noqa: E402
teuthology.setup_log_file(log_file)
if isinstance(func, str):
import importlib
mod_path, _, attr = func.rpartition(".")
mod = importlib.import_module(mod_path)
func = getattr(mod, attr)
Copy link
Member

@VallariAg VallariAg Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to monkeypatch here? Also we can probably import import importlib on top of the file instead of doing it conditionally here? Same with gevent and teuthology imports if possible.

Comment on lines +189 to +194
async def _resolve_auth(request: Request):
"""
Get access token from request.session
Resolve auth from session or Authorization: Bearer header.
Returns (username, token_dict). Validates Bearer tokens against GitHub.

Deprecated: Use resolve_access_token() instead for new code.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably remove this function? I'm most probably missing something here but it seems to me that we introduced this function and then made it deprecated in same commit? 🤔

Comment on lines 182 to 185
raise HTTPException(
status_code=401,
detail="You need to be logged in",
detail="You need to be logged in. Use X-Access-Token header, Authorization: Bearer header, or browser login.",
headers={"WWW-Authenticate": "Bearer"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the header probably needs to be changed since it could be any kind of auth. Same goes for all HTTPExceptions raised in _validate_token_with_github()

token = (direct_token or "").strip()
if token:
log.info("Using X-Access-Token header for auth")
username, token_dict = await _validate_token_with_github(token)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If _validate_token_with_github() fails on any of the validations, then it would throw a HTTPException but we don't catch it anywhere in resolve_access_token()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, we let it be raised in create_run().

Comment on lines +126 to +128
membership_resp = await client.get(
url=GH_FETCH_MEMBERSHIP_URL, headers=headers
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this membership check is done thrice (once here and two times in routes/login.py) - probably better to extract it as a separate function and simply call that everywhere.

detail="Failed to verify organization membership",
headers={"WWW-Authenticate": "Bearer"},
)
return username, {"access_token": token, "token_type": "bearer"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it okay to return "token_type": "bearer" in token_dict here for direct token too? Or I guess we can return the token and create token_dict later in resolve_access_token for each type?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants