diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 26636ce..5583a4e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -147,6 +147,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate Changelog + if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push' run: npx changelogithub # or changelogithub@0.12 if ensure the stable result env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/config/oauth.go b/config/oauth.go index 74aaffa..3d863ec 100644 --- a/config/oauth.go +++ b/config/oauth.go @@ -18,3 +18,9 @@ type OidcOauth struct { ClientSecret string `mapstructure:"client-secret"` RedirectUrl string `mapstructure:"redirect-url"` } + +type LinuxdoOauth struct { + ClientId string `mapstructure:"client-id"` + ClientSecret string `mapstructure:"client-secret"` + RedirectUrl string `mapstructure:"redirect-url"` +} diff --git a/model/oauth.go b/model/oauth.go index 29d8014..218e89e 100644 --- a/model/oauth.go +++ b/model/oauth.go @@ -14,6 +14,7 @@ const ( OauthTypeGoogle string = "google" OauthTypeOidc string = "oidc" OauthTypeWebauth string = "webauth" + OauthTypeLinuxdo string = "linuxdo" PKCEMethodS256 string = "S256" PKCEMethodPlain string = "plain" ) @@ -21,7 +22,7 @@ const ( // Validate the oauth type func ValidateOauthType(oauthType string) error { switch oauthType { - case OauthTypeGithub, OauthTypeGoogle, OauthTypeOidc, OauthTypeWebauth: + case OauthTypeGithub, OauthTypeGoogle, OauthTypeOidc, OauthTypeWebauth, OauthTypeLinuxdo: return nil default: return errors.New("invalid Oauth type") @@ -30,6 +31,7 @@ func ValidateOauthType(oauthType string) error { const ( UserEndpointGithub string = "https://api.github.com/user" + UserEndpointLinuxdo string = "https://connect.linux.do/api/user" IssuerGoogle string = "https://accounts.google.com" ) @@ -60,6 +62,8 @@ func (oa *Oauth) FormatOauthInfo() error { oa.Op = OauthTypeGithub case OauthTypeGoogle: oa.Op = OauthTypeGoogle + case OauthTypeLinuxdo: + oa.Op = OauthTypeLinuxdo } // check if the op is empty, set the default value op := strings.TrimSpace(oa.Op) @@ -152,6 +156,24 @@ func (gu *GithubUser) ToOauthUser() *OauthUser { } } +type LinuxdoUser struct { + OauthUserBase + Id int `json:"id"` + Username string `json:"username"` + Avatar string `json:"avatar_url"` +} + +func (lu *LinuxdoUser) ToOauthUser() *OauthUser { + return &OauthUser{ + OpenId: strconv.Itoa(lu.Id), + Name: lu.Name, + Username: strings.ToLower(lu.Username), + Email: lu.Email, + VerifiedEmail: true, // linux.do 用户邮箱默认已验证 + Picture: lu.Avatar, + } +} + type OauthList struct { Oauths []*Oauth `json:"list"` Pagination diff --git a/service/oauth.go b/service/oauth.go index 74a8ab8..399f042 100644 --- a/service/oauth.go +++ b/service/oauth.go @@ -154,6 +154,18 @@ func (os *OauthService) GithubProvider() *oidc.Provider { }).NewProvider(context.Background()) } +func (os *OauthService) LinuxdoProvider() *oidc.Provider { + return (&oidc.ProviderConfig{ + IssuerURL: "", + AuthURL: "https://connect.linux.do/oauth2/authorize", + TokenURL: "https://connect.linux.do/oauth2/token", + DeviceAuthURL: "", + UserInfoURL: model.UserEndpointLinuxdo, + JWKSURL: "", + Algorithms: nil, + }).NewProvider(context.Background()) +} + // GetOauthConfig retrieves the OAuth2 configuration based on the provider name func (os *OauthService) GetOauthConfig(op string) (err error, oauthInfo *model.Oauth, oauthConfig *oauth2.Config, provider *oidc.Provider) { //err, oauthInfo, oauthConfig = os.getOauthConfigGeneral(op) @@ -182,6 +194,10 @@ func (os *OauthService) GetOauthConfig(op string) (err error, oauthInfo *model.O oauthConfig.Endpoint = github.Endpoint oauthConfig.Scopes = []string{"read:user", "user:email"} provider = os.GithubProvider() + case model.OauthTypeLinuxdo: + provider = os.LinuxdoProvider() + oauthConfig.Endpoint = provider.Endpoint() + oauthConfig.Scopes = []string{"profile"} //case model.OauthTypeGoogle: //google单独出来,可以少一次FetchOidcEndpoint请求 // oauthConfig.Endpoint = google.Endpoint // oauthConfig.Scopes = os.constructScopes(oauthInfo.Scopes) @@ -299,6 +315,16 @@ func (os *OauthService) githubCallback(oauthConfig *oauth2.Config, provider *oid return nil, user.ToOauthUser() } +// linuxdoCallback linux.do回调 +func (os *OauthService) linuxdoCallback(oauthConfig *oauth2.Config, provider *oidc.Provider, code, verifier, nonce string) (error, *model.OauthUser) { + var user = &model.LinuxdoUser{} + err, _ := os.callbackBase(oauthConfig, provider, code, verifier, nonce, user) + if err != nil { + return err, nil + } + return nil, user.ToOauthUser() +} + // oidcCallback oidc回调, 通过code获取用户信息 func (os *OauthService) oidcCallback(oauthConfig *oauth2.Config, provider *oidc.Provider, code, verifier, nonce string) (error, *model.OauthUser) { var user = &model.OidcUser{} @@ -319,6 +345,8 @@ func (os *OauthService) Callback(code, verifier, op, nonce string) (err error, o switch oauthType { case model.OauthTypeGithub: err, oauthUser = os.githubCallback(oauthConfig, provider, code, verifier, nonce) + case model.OauthTypeLinuxdo: + err, oauthUser = os.linuxdoCallback(oauthConfig, provider, code, verifier, nonce) case model.OauthTypeOidc, model.OauthTypeGoogle: err, oauthUser = os.oidcCallback(oauthConfig, provider, code, verifier, nonce) default: