loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Show OAuth2 errors to end users (#25261)

Partially fix #23936


![image](https://github.com/go-gitea/gitea/assets/2114189/8aa7f3ad-a5f0-42ce-a478-289a03bd08a3)


![image](https://github.com/go-gitea/gitea/assets/2114189/bb901e7d-485a-47a5-b68d-9ebe7013a6b2)


![image](https://github.com/go-gitea/gitea/assets/2114189/9a1ce0f3-f011-4baf-8e2f-cc6304bc9703)

authored by

wxiaoguang and committed by
GitHub
73ae7182 39a15623

+48 -10
+1 -1
options/locale/locale_en-US.ini
··· 2901 2901 auths.sspi_default_language_helper = Default language for users automatically created by SSPI auth method. Leave empty if you prefer language to be automatically detected. 2902 2902 auths.tips = Tips 2903 2903 auths.tips.oauth2.general = OAuth2 Authentication 2904 - auths.tips.oauth2.general.tip = When registering a new OAuth2 authentication, the callback/redirect URL should be: <host>/user/oauth2/<Authentication Name>/callback 2904 + auths.tips.oauth2.general.tip = When registering a new OAuth2 authentication, the callback/redirect URL should be: 2905 2905 auths.tip.oauth2_provider = OAuth2 Provider 2906 2906 auths.tip.bitbucket = Register a new OAuth consumer on https://bitbucket.org/account/user/<your username>/oauth-consumers/new and add the permission 'Account' - 'Read' 2907 2907 auths.tip.nextcloud = Register a new OAuth consumer on your instance using the following menu "Settings -> Security -> OAuth 2.0 client"
+19 -3
routers/web/auth/oauth.go
··· 4 4 package auth 5 5 6 6 import ( 7 - stdContext "context" 7 + go_context "context" 8 8 "encoding/base64" 9 9 "errors" 10 10 "fmt" ··· 12 12 "io" 13 13 "net/http" 14 14 "net/url" 15 + "sort" 15 16 "strings" 16 17 17 18 "code.gitea.io/gitea/models/auth" ··· 39 40 "github.com/golang-jwt/jwt/v4" 40 41 "github.com/markbates/goth" 41 42 "github.com/markbates/goth/gothic" 43 + go_oauth2 "golang.org/x/oauth2" 42 44 ) 43 45 44 46 const ( ··· 143 145 IDToken string `json:"id_token,omitempty"` 144 146 } 145 147 146 - func newAccessTokenResponse(ctx stdContext.Context, grant *auth.OAuth2Grant, serverKey, clientKey oauth2.JWTSigningKey) (*AccessTokenResponse, *AccessTokenError) { 148 + func newAccessTokenResponse(ctx go_context.Context, grant *auth.OAuth2Grant, serverKey, clientKey oauth2.JWTSigningKey) (*AccessTokenResponse, *AccessTokenError) { 147 149 if setting.OAuth2.InvalidateRefreshTokens { 148 150 if err := grant.IncreaseCounter(ctx); err != nil { 149 151 return nil, &AccessTokenError{ ··· 886 888 func SignInOAuthCallback(ctx *context.Context) { 887 889 provider := ctx.Params(":provider") 888 890 891 + if ctx.Req.FormValue("error") != "" { 892 + var errorKeyValues []string 893 + for k, vv := range ctx.Req.Form { 894 + for _, v := range vv { 895 + errorKeyValues = append(errorKeyValues, fmt.Sprintf("%s = %s", html.EscapeString(k), html.EscapeString(v))) 896 + } 897 + } 898 + sort.Strings(errorKeyValues) 899 + ctx.Flash.Error(strings.Join(errorKeyValues, "<br>"), true) 900 + } 901 + 889 902 // first look if the provider is still active 890 903 authSource, err := auth.GetActiveOAuth2SourceByName(provider) 891 904 if err != nil { ··· 894 907 } 895 908 896 909 if authSource == nil { 897 - ctx.ServerError("SignIn", errors.New("No valid provider found, check configured callback url in provider")) 910 + ctx.ServerError("SignIn", errors.New("no valid provider found, check configured callback url in provider")) 898 911 return 899 912 } 900 913 ··· 919 932 } 920 933 ctx.Redirect(setting.AppSubURL + "/user/login") 921 934 return 935 + } 936 + if err, ok := err.(*go_oauth2.RetrieveError); ok { 937 + ctx.Flash.Error("OAuth2 RetrieveError: "+err.Error(), true) 922 938 } 923 939 ctx.ServerError("UserSignIn", err) 924 940 return
+13 -2
templates/admin/auth/edit.tmpl
··· 14 14 <span>{{.Source.TypeName}}</span> 15 15 </div> 16 16 <div class="required inline field {{if .Err_Name}}error{{end}}"> 17 - <label for="name">{{.locale.Tr "admin.auths.auth_name"}}</label> 18 - <input id="name" name="name" value="{{.Source.Name}}" autofocus required> 17 + <label for="auth_name">{{.locale.Tr "admin.auths.auth_name"}}</label> 18 + <input id="auth_name" name="name" value="{{.Source.Name}}" autofocus required> 19 19 </div> 20 20 21 21 <!-- LDAP and DLDAP --> ··· 433 433 <button class="ui red button delete-button" data-url="{{$.Link}}/delete" data-id="{{.Source.ID}}">{{.locale.Tr "admin.auths.delete"}}</button> 434 434 </div> 435 435 </form> 436 + </div> 437 + 438 + <h4 class="ui top attached header"> 439 + {{.locale.Tr "admin.auths.tips"}} 440 + </h4> 441 + <div class="ui attached segment"> 442 + <h5>GMail Settings:</h5> 443 + <p>Host: smtp.gmail.com, Port: 587, Enable TLS Encryption: true</p> 444 + 445 + <h5 class="oauth2">{{.locale.Tr "admin.auths.tips.oauth2.general"}}:</h5> 446 + <p class="oauth2">{{.locale.Tr "admin.auths.tips.oauth2.general.tip"}} <b id="oauth2-callback-url"></b></p> 436 447 </div> 437 448 </div> 438 449
+4 -4
templates/admin/auth/new.tmpl
··· 22 22 </div> 23 23 </div> 24 24 <div class="required inline field {{if .Err_Name}}error{{end}}"> 25 - <label for="name">{{.locale.Tr "admin.auths.auth_name"}}</label> 26 - <input id="name" name="name" value="{{.name}}" autofocus required> 25 + <label for="auth_name">{{.locale.Tr "admin.auths.auth_name"}}</label> 26 + <input id="auth_name" name="name" value="{{.name}}" autofocus required> 27 27 </div> 28 28 29 29 <!-- LDAP and DLDAP --> ··· 85 85 <h5>GMail Settings:</h5> 86 86 <p>Host: smtp.gmail.com, Port: 587, Enable TLS Encryption: true</p> 87 87 88 - <h5>{{.locale.Tr "admin.auths.tips.oauth2.general"}}:</h5> 89 - <p>{{.locale.Tr "admin.auths.tips.oauth2.general.tip"}}</p> 88 + <h5 class="oauth2">{{.locale.Tr "admin.auths.tips.oauth2.general"}}:</h5> 89 + <p class="oauth2">{{.locale.Tr "admin.auths.tips.oauth2.general.tip"}} <b id="oauth2-callback-url"></b></p> 90 90 91 91 <h5 class="ui top attached header">{{.locale.Tr "admin.auths.tip.oauth2_provider"}}</h5> 92 92 <div class="ui attached segment">
+5
templates/status/500.tmpl
··· 1 1 {{/* This page should only depend the minimal template functions/variables, to avoid triggering new panics. 2 2 * base template functions: AppName, AssetUrlPrefix, AssetVersion, AppSubUrl, DefaultTheme, Str2html 3 3 * locale 4 + * Flash 4 5 * ErrorMsg 5 6 * SignedUser (optional) 6 7 */}} ··· 28 29 </div> 29 30 </nav> 30 31 <div role="main" class="page-content status-page-500"> 32 + <div class="ui container" > 33 + <style> .ui.message.flash-message { text-align: left; } </style> 34 + {{template "base/alert" .}} 35 + </div> 31 36 <p class="gt-mt-5 center"><img src="{{AssetUrlPrefix}}/img/500.png" alt="Internal Server Error"></p> 32 37 <div class="ui divider"></div> 33 38 <div class="ui container gt-my-5">
+6
web_src/js/features/admin/common.js
··· 171 171 } 172 172 } 173 173 174 + if ($('.admin.authentication').length > 0) { 175 + $('#auth_name').on('input', function () { 176 + $('#oauth2-callback-url').text(`${window.location.origin}/user/oauth2/${encodeURIComponent($(this).val())}/callback`); 177 + }).trigger('input'); 178 + } 179 + 174 180 // Notice 175 181 if ($('.admin.notice')) { 176 182 const $detailModal = $('#detail-modal');