浏览代码

Refa: Deprecate `/github_callback` in favor of `/oauth/callback/<channel>` for GitHub OAuth integration (#7587)

### What problem does this PR solve?

Deprecate `/github_callback` route in favor of
`/oauth/callback/<channel>` for GitHub OAuth integration:

- Added GitHub OAuth support in the authentication module
- Introduced `GithubOAuthClient` with methods to fetch and normalize
user info
  - Updated `CLIENT_TYPES` to include GitHub OAuth client
- Deprecated `/github_callback` route and suggested using the generic
`/oauth/callback/<channel>` route

---
- Related pull requests: 
  - #7379
  - #7553 

### Usage

- [Create a GitHub OAuth
App](https://github.com/settings/applications/new) to obtain the
`client_id` and `client_secret`, configure the authorization callback
url: `https://your-app.com/v1/user/oauth/callback/github`
- Edit `service_conf.yaml.template`:
  ```yaml
  # ...
  oauth:
    github:
      type: "github"
      icon: "github"
      display_name: "Github"
      client_id: "your_client_id"
      client_secret: "your_client_secret"
      redirect_uri: "https://your-app.com/v1/user/oauth/callback/github"
  # ...
  ```

### Type of change

- [x] Documentation Update
- [x] Refactoring (non-breaking change)
tags/v0.19.0
Chaoxi Weng 5 个月前
父节点
当前提交
a8542508b7
没有帐户链接到提交者的电子邮件
共有 6 个文件被更改,包括 87 次插入6 次删除
  1. 9
    1
      api/apps/auth/README.md
  2. 3
    1
      api/apps/auth/__init__.py
  3. 63
    0
      api/apps/auth/github.py
  4. 2
    0
      api/apps/user_app.py
  5. 5
    2
      conf/service_conf.yaml
  6. 5
    2
      docker/service_conf.yaml.template

+ 9
- 1
api/apps/auth/README.md 查看文件

@@ -32,8 +32,16 @@ oidc_config = {
"redirect_uri": "https://your-app.com/v1/user/oauth/callback/<channel>"
}

# Github OAuth configuration
github_config = {
"type": "github"
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"redirect_uri": "https://your-app.com/v1/user/oauth/callback/<channel>"
}

# Get client instance
client = get_auth_client(oauth_config) # or oidc_config
client = get_auth_client(oauth_config)
```

### Authentication Flow

+ 3
- 1
api/apps/auth/__init__.py 查看文件

@@ -16,11 +16,13 @@

from .oauth import OAuthClient
from .oidc import OIDCClient
from .github import GithubOAuthClient


CLIENT_TYPES = {
"oauth2": OAuthClient,
"oidc": OIDCClient
"oidc": OIDCClient,
"github": GithubOAuthClient
}



+ 63
- 0
api/apps/auth/github.py 查看文件

@@ -0,0 +1,63 @@
#
# Copyright 2025 The InfiniFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import requests
from .oauth import OAuthClient, UserInfo


class GithubOAuthClient(OAuthClient):
def __init__(self, config):
"""
Initialize the GithubOAuthClient with the provider's configuration.
"""
config.update({
"authorization_url": "https://github.com/login/oauth/authorize",
"token_url": "https://github.com/login/oauth/access_token",
"userinfo_url": "https://api.github.com/user",
"scope": "user:email"
})
super().__init__(config)


def fetch_user_info(self, access_token, **kwargs):
"""
Fetch github user info.
"""
user_info = {}
try:
headers = {"Authorization": f"Bearer {access_token}"}
# user info
response = requests.get(self.userinfo_url, headers=headers, timeout=self.http_request_timeout)
response.raise_for_status()
user_info.update(response.json())
# email info
response = requests.get(self.userinfo_url+"/emails", headers=headers, timeout=self.http_request_timeout)
response.raise_for_status()
email_info = response.json()
user_info["email"] = next(
(email for email in email_info if email["primary"]), None
)["email"]
return self.normalize_user_info(user_info)
except requests.exceptions.RequestException as e:
raise ValueError(f"Failed to fetch github user info: {e}")


def normalize_user_info(self, user_info):
email = user_info.get("email")
username = user_info.get("login", str(email).split("@")[0])
nickname = user_info.get("name", username)
avatar_url = user_info.get("avatar_url", "")
return UserInfo(email=email, username=username, nickname=nickname, avatar_url=avatar_url)

+ 2
- 0
api/apps/user_app.py 查看文件

@@ -233,6 +233,8 @@ def oauth_callback(channel):
@manager.route("/github_callback", methods=["GET"]) # noqa: F821
def github_callback():
"""
**Deprecated**, Use `/oauth/callback/<channel>` instead.

GitHub OAuth callback endpoint.
---
tags:

+ 5
- 2
conf/service_conf.yaml 查看文件

@@ -64,9 +64,12 @@ redis:
# base_url: ''
# oauth:
# github:
# type: github
# icon: github
# display_name: "Github"
# client_id: xxxxxxxxxxxxxxxxxxxxxxxxx
# secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
# url: https://github.com/login/oauth/access_token
# client_secret: xxxxxxxxxxxxxxxxxxxxxxxx
# redirect_uri: https://your-app.com/v1/user/oauth/callback/github
# feishu:
# app_id: cli_xxxxxxxxxxxxxxxxxxx
# app_secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxx

+ 5
- 2
docker/service_conf.yaml.template 查看文件

@@ -76,9 +76,12 @@ redis:
# image2text_model: ''
# oauth:
# github:
# type: github
# icon: github
# display_name: "Github"
# client_id: xxxxxxxxxxxxxxxxxxxxxxxxx
# secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
# url: https://github.com/login/oauth/access_token
# client_secret: xxxxxxxxxxxxxxxxxxxxxxxx
# redirect_uri: https://your-app.com/v1/user/oauth/callback/github
# feishu:
# app_id: cli_xxxxxxxxxxxxxxxxxxx
# app_secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxx

正在加载...
取消
保存