1
1
mirror of https://github.com/go-gitea/gitea.git synced 2025-02-14 07:41:21 +01:00

Modify OAuth login ui and fix display name, iconurl related logic (#25030)

Close #24808 

Co-Authour @wxiaoguang @silverwind 

1. Most svgs are found from https://worldvectorlogo.com/ , and some are
from conversion of png to svg. (facebook and nextcloud). And also
changed `templates/user/settings/security/accountlinks.tmpl`.

2. Fixed display name and iconurl related logic

# After

<img width="1436" alt="Screen Shot 2023-06-05 at 14 09 05"
src="https://github.com/go-gitea/gitea/assets/17645053/a5db39d8-1ab0-4676-82a4-fba60a1d1f84">

On mobile

<img width="378" alt="Screen Shot 2023-06-05 at 14 09 46"
src="https://github.com/go-gitea/gitea/assets/17645053/71d0f51b-baac-4f48-8ca2-ae0e013bd62e">


user/settings/security/accountlinks (The dropdown might be improved
later)

<img width="973" alt="Screen Shot 2023-06-01 at 10 01 44"
src="https://github.com/go-gitea/gitea/assets/17645053/27010e7e-2785-4fc5-8c49-b06621898f37">

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
HesterG 2023-06-09 00:35:29 +08:00 committed by GitHub
parent 9aaaf980f0
commit 63a429581c
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 80 additions and 270 deletions

@ -4,7 +4,8 @@ explore = Explore
help = Help
logo = Logo
sign_in = Sign In
sign_in_with = Sign In With
sign_in_with_provider = Sign in with %s
sign_in_or = or
sign_out = Sign Out
sign_up = Register
link_account = Link Account

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="25 24.999 850 790.592" class="svg gitea-dropbox" width="16" height="16" aria-hidden="true"><g fill="#007ee5"><path d="M275.037 24.999 25 188.255l172.886 138.448L450 171.023zM25 465.16l250.037 163.256L450 482.374l-252.114-155.67zm425 17.214 174.963 146.042L875 465.16 702.114 326.703z"/><path d="M875 188.255 624.963 24.999 450 171.024l252.114 155.68zM450.513 513.797l-175.476 145.61-75.09-49.028v54.959L450.513 815.59 701.08 665.338v-54.96l-75.09 49.029z"/></g></svg>

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="svg octicon-mark-github" width="16" height="16" aria-hidden="true"><path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"/></svg>

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48" class="svg gitea-google" width="16" height="16" aria-hidden="true"><defs><path id="gitea-google__a" d="M44.5 20H24v8.5h11.8C34.7 33.9 30.1 37 24 37c-7.2 0-13-5.8-13-13s5.8-13 13-13c3.1 0 5.9 1.1 8.1 2.9l6.4-6.4C34.6 4.1 29.6 2 24 2 11.8 2 2 11.8 2 24s9.8 22 22 22c11 0 21-8 21-22 0-1.3-.2-2.7-.5-4z"/></defs><clipPath id="gitea-google__b"><use xlink:href="#gitea-google__a" overflow="visible"/></clipPath><path fill="#FBBC05" d="M0 37V11l17 13z" clip-path="url(#gitea-google__b)"/><path fill="#EA4335" d="m0 11 17 13 7-6.1L48 14V0H0z" clip-path="url(#gitea-google__b)"/><path fill="#34A853" d="m0 37 30-23 7.9 1L48 0v48H0z" clip-path="url(#gitea-google__b)"/><path fill="#4285F4" d="M48 48 17 24l-4-3 35-10z" clip-path="url(#gitea-google__b)"/></svg>

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 792 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2075 2499.8" class="svg gitea-microsoftonline" width="16" height="16" aria-hidden="true"><path fill="#eb3c00" d="M0 2016.6V496.8L1344.4 0 2075 233.7v2045.9l-730.6 220.3L0 2016.6l1344.4 161.8V409.2L467.6 613.8v1198.3z"/></svg>

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 826 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" class="svg gitea-yandex" width="16" height="16" aria-hidden="true"><path fill="#e52620" d="M49.07 0c.524.405.262.88.095 1.333l-6.643 18.095-8.047 22.12a4.21 4.21 0 0 0-.262 1.429v19.81c0 1.2-.024 1.2-1.214 1.2-1.238 0-2.476-.048-3.714.024-.786.024-1.07-.238-1.048-1.024l.024-7.333V42.928c0-.5-.07-1.048-.262-1.524L14.976 7.333c-.095-.262-.238-.476-.357-.714v-.5c.38-.12.762-.3 1.143-.3l4.12-.024s1.357 0 1.81 1.286l9.7 27.31.405.976.333-1.095 1.905-6.976 8.5-26.31c.12-.333.405-.62.62-.93L49.07 0z"/></svg>

After

Width:  |  Height:  |  Size: 566 B

@ -61,7 +61,7 @@ func UserSignIn(username, password string) (*user_model.User, *auth.Source, erro
}
if !source.IsActive {
return nil, nil, oauth2.ErrAuthSourceNotActived
return nil, nil, oauth2.ErrAuthSourceNotActivated
}
authenticator, ok := source.Cfg.(PasswordAuthenticator)

@ -19,7 +19,7 @@ import (
type Provider interface {
Name() string
DisplayName() string
Image() string
IconURL() string
CustomURLSettings() *CustomURLSettings
}
@ -34,23 +34,28 @@ type GothProvider interface {
GothProviderCreator
}
// ImagedProvider provide an overridden image setting for the provider
type ImagedProvider struct {
// AuthSourceProvider provides a provider for an AuthSource. Multiple auth sources could use the same registered GothProvider
// So each auth source should have its own DisplayName and IconURL for display.
// The Name is the GothProvider's name, to help to find the GothProvider to sign in.
// The DisplayName is the auth source config's name, site admin set it on the admin page, the IconURL can also be set there.
type AuthSourceProvider struct {
GothProvider
image string
sourceName, iconURL string
}
// Image returns the image path for this provider
func (i *ImagedProvider) Image() string {
return i.image
func (p *AuthSourceProvider) Name() string {
return p.GothProvider.Name()
}
// NewImagedProvider is a constructor function for the ImagedProvider
func NewImagedProvider(image string, provider GothProvider) *ImagedProvider {
return &ImagedProvider{
GothProvider: provider,
image: image,
func (p *AuthSourceProvider) DisplayName() string {
return p.sourceName
}
func (p *AuthSourceProvider) IconURL() string {
if p.iconURL != "" {
return p.iconURL
}
return p.GothProvider.IconURL()
}
// Providers contains the map of registered OAuth2 providers in Gitea (based on goth)
@ -95,11 +100,13 @@ func GetActiveOAuth2Providers() ([]string, map[string]Provider, error) {
var orderedKeys []string
providers := make(map[string]Provider)
for _, source := range authSources {
prov := gothProviders[source.Cfg.(*Source).Provider]
if source.Cfg.(*Source).IconURL != "" {
prov = &ImagedProvider{prov, source.Cfg.(*Source).IconURL}
oauth2Cfg, ok := source.Cfg.(*Source)
if !ok {
log.Error("Invalid OAuth2 source config: %v", oauth2Cfg)
continue
}
providers[source.Name] = prov
gothProv := gothProviders[oauth2Cfg.Provider]
providers[source.Name] = &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL}
orderedKeys = append(orderedKeys, source.Name)
}
@ -138,8 +145,7 @@ func ClearProviders() {
goth.ClearProviders()
}
// ErrAuthSourceNotActived login source is not actived error
var ErrAuthSourceNotActived = errors.New("auth source is not actived")
var ErrAuthSourceNotActivated = errors.New("auth source is not activated")
// used to create different types of goth providers
func createProvider(providerName string, source *Source) (goth.Provider, error) {
@ -150,7 +156,7 @@ func createProvider(providerName string, source *Source) (goth.Provider, error)
p, ok := gothProviders[source.Provider]
if !ok {
return nil, ErrAuthSourceNotActived
return nil, ErrAuthSourceNotActivated
}
provider, err = p.CreateGothProvider(providerName, callbackURL, source)

@ -3,6 +3,8 @@
package oauth2
import "code.gitea.io/gitea/modules/setting"
// BaseProvider represents a common base for Provider
type BaseProvider struct {
name string
@ -19,9 +21,14 @@ func (b *BaseProvider) DisplayName() string {
return b.displayName
}
// Image returns an image path for this provider
func (b *BaseProvider) Image() string {
return "/assets/img/auth/" + b.name + ".png"
// IconURL returns an icon path for this provider
// Use svg for default icons, providers_openid has its own IconURL function
func (b *BaseProvider) IconURL() string {
name := b.name
if b.name == "gplus" {
name = "google"
}
return setting.AppSubURL + "/assets/img/auth/" + name + ".svg"
}
// CustomURLSettings returns the custom url settings for this provider
@ -29,4 +36,4 @@ func (b *BaseProvider) CustomURLSettings() *CustomURLSettings {
return nil
}
var _ (Provider) = &BaseProvider{}
var _ Provider = &BaseProvider{}

@ -49,7 +49,7 @@ func NewCustomProvider(name, displayName string, customURLSetting *CustomURLSett
}
}
var _ (GothProvider) = &CustomProvider{}
var _ GothProvider = &CustomProvider{}
func init() {
RegisterGothProvider(NewCustomProvider(

@ -24,9 +24,9 @@ func (o *OpenIDProvider) DisplayName() string {
return "OpenID Connect"
}
// Image returns an image path for this provider
func (o *OpenIDProvider) Image() string {
return "/assets/img/auth/openid_connect.svg"
// IconURL returns an icon path for this provider
func (o *OpenIDProvider) IconURL() string {
return setting.AppSubURL + "/assets/img/svg/gitea-openid.svg"
}
// CreateGothProvider creates a GothProvider from this Provider
@ -48,7 +48,7 @@ func (o *OpenIDProvider) CustomURLSettings() *CustomURLSettings {
return nil
}
var _ (GothProvider) = &OpenIDProvider{}
var _ GothProvider = &OpenIDProvider{}
func init() {
RegisterGothProvider(&OpenIDProvider{})

@ -48,7 +48,7 @@ func NewSimpleProvider(name, displayName string, scopes []string, newFn SimplePr
}
}
var _ (GothProvider) = &SimpleProvider{}
var _ GothProvider = &SimpleProvider{}
func init() {
RegisterGothProvider(
@ -69,13 +69,13 @@ func init() {
}))
// named gplus due to legacy gplus -> google migration (Google killed Google+). This ensures old connections still work
RegisterGothProvider(NewImagedProvider("/assets/img/auth/google.png", NewSimpleProvider("gplus", "Google", []string{"email"},
RegisterGothProvider(NewSimpleProvider("gplus", "Google", []string{"email"},
func(clientKey, secret, callbackURL string, scopes ...string) goth.Provider {
if setting.OAuth2Client.UpdateAvatar || setting.OAuth2Client.EnableAutoRegistration {
scopes = append(scopes, "profile")
}
return google.New(clientKey, secret, callbackURL, scopes...)
})))
}))
RegisterGothProvider(NewSimpleProvider("twitter", "Twitter", nil,
func(clientKey, secret, callbackURL string, scopes ...string) goth.Provider {

@ -53,29 +53,17 @@
{{end}}
{{if and .OrderedOAuth2Names .OAuth2Providers}}
<hr class="ui divider"/>
<div id="oauth2-login-navigator">
<div id="oauth2-login-navigator-inner" class="gt-df gt-jc">
<span class="gt-self-center gt-mr-3">{{.locale.Tr "sign_in_with"}}</span>
<div class="gt-df gt-fw gt-gap-4">
<div class="gt-df gt-fc gt-jc">
<div class="ui horizontal divider">
{{.locale.Tr "sign_in_or"}}
</div>
<div id="oauth2-login-navigator-inner" class="gt-df gt-fc gt-fw gt-ac gt-gap-3">
{{range $key := .OrderedOAuth2Names}}
{{$provider := index $.OAuth2Providers $key}}
<a class="{{$provider.Name}} silenced oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$key}}" data-tooltip-content="{{$provider.DisplayName}}{{if eq $provider.Name "openidConnect"}} ({{$key}}){{end}}">
{{if eq $provider.Name "github"}}
{{svg "octicon-mark-github" 40}}
{{else if eq $provider.Name "gitlab"}}
{{svg "gitea-gitlab" 40}}
{{else if eq $provider.Name "openidConnect"}}
{{svg "gitea-openid" 40}}
{{else}}
<img
class="gt-object-contain"
width="40"
height="40"
alt="{{$provider.DisplayName}}{{if eq $provider.Name "openidConnect"}} ({{$key}}){{end}}"
src="{{AppSubUrl}}{{$provider.Image}}"
>
{{end}}
<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
<img class="gt-mr-3" width="20" height="20" src="{{$provider.IconURL}}" alt="{{$provider.DisplayName}}">
{{$.locale.Tr "sign_in_with_provider" $provider.DisplayName}}
</a>
{{end}}
</div>

@ -8,7 +8,7 @@
{{range $key := .OrderedOAuth2Names}}
{{$provider := index $.OAuth2Providers $key}}
<a class="item" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
<img width="20" height="20" src="{{AppSubUrl}}{{$provider.Image}}" alt="{{$provider.DisplayName}}">
<img class="gt-mr-3" width="20" height="20" src="{{$provider.IconURL}}" alt="{{$provider.DisplayName}}">
{{$provider.DisplayName}}
</a>
{{end}}

@ -468,6 +468,10 @@ a.label,
padding-bottom: 7.42px !important;
}
.ui.divider {
color: var(--color-text);
}
.ui.divider:not(.vertical,.horizontal) {
border-top-color: var(--color-secondary) !important;
border-bottom: none !important;

@ -309,7 +309,8 @@ textarea:focus,
.user.reset.password form .inline.field > textarea,
.user.link-account form .inline.field > textarea,
.user.signin form .inline.field > textarea,
.user.signup form .inline.field > textarea {
.user.signup form .inline.field > textarea,
.oauth-login-link {
width: 50%;
}
}
@ -364,7 +365,8 @@ textarea:focus,
.user.reset.password form input,
.user.link-account form input,
.user.signin form input,
.user.signup form input {
.user.signup form input,
.oauth-login-link {
width: 100% !important;
}
}

@ -7,3 +7,4 @@
@disabledOpacity: var(--opacity-disabled);
@variationPopupTooltip: false;
@linkHoverUnderline: underline;
@variationButtonSocial: false;

@ -439,219 +439,6 @@
border-bottom-right-radius: 0;
}
/*-------------------
Social
--------------------*/
/* Facebook */
.ui.facebook.button {
background-color: #3B5998;
color: #FFFFFF;
text-shadow: none;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.facebook.button:hover {
background-color: #304d8a;
color: #FFFFFF;
text-shadow: none;
}
.ui.facebook.button:active {
background-color: #2d4373;
color: #FFFFFF;
text-shadow: none;
}
/* Twitter */
.ui.twitter.button {
background-color: #1DA1F2;
color: #FFFFFF;
text-shadow: none;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.twitter.button:hover {
background-color: #0298f3;
color: #FFFFFF;
text-shadow: none;
}
.ui.twitter.button:active {
background-color: #0c85d0;
color: #FFFFFF;
text-shadow: none;
}
/* Google Plus */
.ui.google.plus.button {
background-color: #DD4B39;
color: #FFFFFF;
text-shadow: none;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.google.plus.button:hover {
background-color: #e0321c;
color: #FFFFFF;
text-shadow: none;
}
.ui.google.plus.button:active {
background-color: #c23321;
color: #FFFFFF;
text-shadow: none;
}
/* Linked In */
.ui.linkedin.button {
background-color: #0077B5;
color: #FFFFFF;
text-shadow: none;
}
.ui.linkedin.button:hover {
background-color: #00669c;
color: #FFFFFF;
text-shadow: none;
}
.ui.linkedin.button:active {
background-color: #005582;
color: #FFFFFF;
text-shadow: none;
}
/* YouTube */
.ui.youtube.button {
background-color: #FF0000;
color: #FFFFFF;
text-shadow: none;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.youtube.button:hover {
background-color: #e60000;
color: #FFFFFF;
text-shadow: none;
}
.ui.youtube.button:active {
background-color: #cc0000;
color: #FFFFFF;
text-shadow: none;
}
/* Instagram */
.ui.instagram.button {
background-color: #49769C;
color: #FFFFFF;
text-shadow: none;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.instagram.button:hover {
background-color: #3d698e;
color: #FFFFFF;
text-shadow: none;
}
.ui.instagram.button:active {
background-color: #395c79;
color: #FFFFFF;
text-shadow: none;
}
/* Pinterest */
.ui.pinterest.button {
background-color: #BD081C;
color: #FFFFFF;
text-shadow: none;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.pinterest.button:hover {
background-color: #ac0013;
color: #FFFFFF;
text-shadow: none;
}
.ui.pinterest.button:active {
background-color: #8c0615;
color: #FFFFFF;
text-shadow: none;
}
/* VK */
.ui.vk.button {
background-color: #45668E;
color: #FFFFFF;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.vk.button:hover {
background-color: #395980;
color: #FFFFFF;
}
.ui.vk.button:active {
background-color: #344d6c;
color: #FFFFFF;
}
/* WhatsApp */
.ui.whatsapp.button {
background-color: #25D366;
color: #FFFFFF;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.whatsapp.button:hover {
background-color: #19c55a;
color: #FFFFFF;
}
.ui.whatsapp.button:active {
background-color: #1da851;
color: #FFFFFF;
}
/* Telegram */
.ui.telegram.button {
background-color: #0088CC;
color: #FFFFFF;
background-image: none;
box-shadow: 0 0 0 0 rgba(34, 36, 38, 0.15) inset;
}
.ui.telegram.button:hover {
background-color: #0077b3;
color: #FFFFFF;
}
.ui.telegram.button:active {
background-color: #006699;
color: #FFFFFF;
}
/*--------------
Icon
---------------*/