yanyongyu / githubkit

The modern, all-batteries-included GitHub SDK for Python, including rest api, graphql, webhooks, like octokit!
https://yanyongyu.github.io/githubkit/
MIT License
198 stars 25 forks source link

Readme need to Update (Suggestion) for oauth app #125

Closed BhuwanPandey closed 2 months ago

BhuwanPandey commented 2 months ago

Develop an OAuth APP with web flow


from githubkit.versions.latest.models import PublicUser, PrivateUser
from githubkit import GitHub, OAuthAppAuthStrategy, OAuthTokenAuthStrategy

github = GitHub(OAuthAppAuthStrategy("<client_id>", "<client_secret>"))

# redirect user to github oauth page and get the code from callback

# one time usage
user_github = github.with_auth(github.auth.as_web_user("<code>"))

# or, store the user token in a database
auth: OAuthTokenAuthStrategy = github.auth.as_web_user("<code>").exchange_token(github)
access_token = auth.token
refresh_token = auth.refresh_token
# restore the user token from database
user_github = github.with_auth(
    OAuthTokenAuthStrategy(
        "<client_id>", "<client_secret>", refresh_token=refresh_token
    )
)

# now you can act as the user
resp = user_github.rest.users.get_authenticated()
user: PublicUser | PrivateUser = resp.parsed_data

I think these need to be updated as


from githubkit.versions.latest.models import PublicUser, PrivateUser
from githubkit import GitHub, OAuthAppAuthStrategy, OAuthTokenAuthStrategy

github = GitHub(OAuthAppAuthStrategy("<client_id>", "<client_secret>"))

# redirect user to github oauth page and get the code from callback

# one time usage
user_github = github.with_auth(github.auth.as_web_user("<code>"))

# or, store the user token in a database
auth: OAuthTokenAuthStrategy = github.auth.as_web_user("<code>").exchange_token(github)
token= auth.token
# restore the user token from database
user_github = github.with_auth(
    OAuthTokenAuthStrategy(
        "<client_id>", "<client_secret>", token=token 
    )
)

# now you can act as the user
resp = user_github.rest.users.get_authenticated()
user: PublicUser | PrivateUser = resp.parsed_data
# now you can get email address
email = user_github.rest.users.list_emails_for_authenticated_user()

There is no opt-in feature available on oauth app but github app provide this feature. that a reason , oauth app always return accesstoken instead of refresh_token . I think , we shouldnot need to mention refresh_token as it's value is always None. and I can't able to get user email directly from above user object like

user.email , it return None

so to get email address , we have to do like

email = user_github.rest.users.list_emails_for_authenticated_user()

If all sounds good to you, I will be happy to create PR.

yanyongyu commented 2 months ago

GitHub APP can be also used as an oauth app. Maybe we could change the title and add some comments for refresh token in the code.

Saschl commented 2 months ago

What the purpose of this? How it related to this issue

Please do not open this, my account got compromised. I’m very sorry about that.

BhuwanPandey commented 2 months ago

what will be if we update documentation like

Develop an OAuth APP/GitHub APP with web flow

from githubkit.versions.latest.models import PublicUser, PrivateUser
from githubkit import GitHub, OAuthAppAuthStrategy, OAuthTokenAuthStrategy

github = GitHub(OAuthAppAuthStrategy("<client_id>", "<client_secret>"))

# redirect user to github oauth page and get the code from callback

# one time usage
user_github = github.with_auth(github.auth.as_web_user("<code>"))

# or, store the user token in a database
auth: OAuthTokenAuthStrategy = github.auth.as_web_user("<code>").exchange_token(github)
access_token = auth.token
refresh_token = auth.refresh_token
# restore the user token from database

# With  OAuthAPP
user_github = github.with_auth(
    OAuthTokenAuthStrategy(
        "<client_id>", "<client_secret>", token=access_token 
    )
)
# OR  with  GithubAPP
user_github = github.with_auth(
    OAuthTokenAuthStrategy(
        "<client_id>", "<client_secret>", refresh_token=refresh_token 
    )
)

# now you can act as the user
resp = user_github.rest.users.get_authenticated()
user: PublicUser | PrivateUser = resp.parsed_data

still I amnot able to figure out how to get user email

user.email return None , I have tested for both oauth and github app.
yanyongyu commented 2 months ago

what will be if we update documentation like

you can just open a pr and i will review it.

still I amnot able to figure out how to get user email

user.email is the public email for the user account. It may be None because user can make it private. As described in the github docs, you can use the list_emails_for_authenticated_user endpoint instead. Note that:

OAuth app tokens and personal access tokens (classic) need the user:email scope to use this endpoint.

yanyongyu commented 2 months ago

I found that the refresh_token will become invalid once it is used and user should store the new refresh token. I miss this in the docs. I will add this later.

You can use the refresh token to generate a new user access token and a new refresh token. Once you use a refresh token, that refresh token and the old user access token will no longer work.