Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: support app jwt auth using client id #129

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions githubkit/auth/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"""GitHub App or Installation Authentication Hook"""

github: "GitHubCore"
app_id: Union[str, int]
app_id: Union[str, int, None]
private_key: str
client_id: Optional[str] = None
client_secret: Optional[str] = None
Expand All @@ -39,12 +39,22 @@
permissions: Union[Unset, "AppPermissionsType"] = UNSET
cache: "BaseCache" = DEFAULT_CACHE

JWT_CACHE_KEY = "githubkit:auth:app:{app_id}:jwt"
JWT_CACHE_KEY = "githubkit:auth:app:{issuer}:jwt"
INSTALLATION_CACHE_KEY = (
"githubkit:auth:app:{app_id}:installation:"
"githubkit:auth:app:{issuer}:installation:"
"{installation_id}:{permissions}:{repositories}:{repository_ids}"
)

@property
def issuer(self) -> str:
# issuer can be either app_id or client_id
issuer = self.client_id if self.app_id is None else self.app_id
if issuer is None:
raise AuthCredentialError(

Check warning on line 53 in githubkit/auth/app.py

View check run for this annotation

Codecov / codecov/patch

githubkit/auth/app.py#L51-L53

Added lines #L51 - L53 were not covered by tests
"Either app_id or client_id must be provided for GitHub APP"
)
return str(issuer)

Check warning on line 56 in githubkit/auth/app.py

View check run for this annotation

Codecov / codecov/patch

githubkit/auth/app.py#L56

Added line #L56 was not covered by tests

def _get_api_route(self, url: httpx.URL) -> httpx.URL:
"""Get the api route (path only) for the given url."""
base_url_path = self.github.config.base_url.path
Expand All @@ -65,16 +75,17 @@
"JWT support for GitHub APP should be installed "
"with `pip install githubkit[auth-app]`"
)

time = datetime.now(timezone.utc) - timedelta(minutes=1)
expire_time = time + timedelta(minutes=10)
return jwt.encode(
{"iss": str(self.app_id), "iat": time, "exp": expire_time},
{"iss": self.issuer, "iat": time, "exp": expire_time},
self.private_key,
algorithm="RS256",
)

def _get_jwt_cache_key(self) -> str:
return self.JWT_CACHE_KEY.format(app_id=self.app_id)
return self.JWT_CACHE_KEY.format(issuer=self.issuer)

Check warning on line 88 in githubkit/auth/app.py

View check run for this annotation

Codecov / codecov/patch

githubkit/auth/app.py#L88

Added line #L88 was not covered by tests

def get_jwt(self) -> str:
cache_key = self._get_jwt_cache_key()
Expand Down Expand Up @@ -159,7 +170,7 @@
[] if isinstance(self.repository_ids, Unset) else self.repository_ids
)
return self.INSTALLATION_CACHE_KEY.format(
app_id=self.app_id,
issuer=self.issuer,
installation_id=self.installation_id,
permissions=",".join(
name if value == "read" else f"{name}!"
Expand Down Expand Up @@ -247,12 +258,19 @@
class AppAuthStrategy(BaseAuthStrategy):
"""GitHub App Authentication"""

app_id: Union[str, int]
app_id: Union[str, int, None]
private_key: str
client_id: Optional[str] = None
client_secret: Optional[str] = None
cache: "BaseCache" = DEFAULT_CACHE

def __post_init__(self):
# either app_id or client_id must be provided
if self.app_id is None and self.client_id is None:
raise AuthCredentialError(

Check warning on line 270 in githubkit/auth/app.py

View check run for this annotation

Codecov / codecov/patch

githubkit/auth/app.py#L269-L270

Added lines #L269 - L270 were not covered by tests
"Either app_id or client_id must be provided for GitHub APP"
)

def as_installation(
self,
installation_id: int,
Expand Down Expand Up @@ -294,7 +312,7 @@
class AppInstallationAuthStrategy(BaseAuthStrategy):
"""GitHub App Installation Authentication"""

app_id: Union[str, int]
app_id: Union[str, int, None]
private_key: str
installation_id: int
client_id: Optional[str] = None
Expand All @@ -304,6 +322,13 @@
permissions: Union[Unset, "AppPermissionsType"] = UNSET
cache: "BaseCache" = DEFAULT_CACHE

def __post_init__(self):
# either app_id or client_id must be provided
if self.app_id is None and self.client_id is None:
raise AuthCredentialError(

Check warning on line 328 in githubkit/auth/app.py

View check run for this annotation

Codecov / codecov/patch

githubkit/auth/app.py#L327-L328

Added lines #L327 - L328 were not covered by tests
"Either app_id or client_id must be provided for GitHub APP"
)

def as_app(self) -> AppAuthStrategy:
return AppAuthStrategy(
self.app_id,
Expand Down
Loading