Disable Gravatar (#37)

* Disable Gravatar
* Lowercase emails
* Add migration
هذا الالتزام موجود في:
Thomas Miceli
2023-05-26 09:15:37 +02:00
ملتزم من قبل GitHub
الأصل 7cc77d80dc
التزام 4a75a50370
17 ملفات معدلة مع 138 إضافات و17 حذوفات

عرض الملف

@@ -13,6 +13,7 @@ const (
SettingDisableSignup = "disable-signup"
SettingRequireLogin = "require-login"
SettingDisableLoginForm = "disable-login-form"
SettingDisableGravatar = "disable-gravatar"
)
func GetSetting(key string) (string, error) {

عرض الملف

@@ -30,6 +30,7 @@ func Setup(dbpath string) error {
SettingDisableSignup: "0",
SettingRequireLogin: "0",
SettingDisableLoginForm: "0",
SettingDisableGravatar: "0",
})
}

عرض الملف

@@ -28,6 +28,7 @@ func ApplyMigrations(db *gorm.DB) error {
Func func(*gorm.DB) error
}{
{1, v1_modifyConstraintToSSHKeys},
{2, v2_lowercaseEmails},
// Add more migrations here as needed
}
@@ -94,3 +95,9 @@ func v1_modifyConstraintToSSHKeys(db *gorm.DB) error {
renameSQL := `ALTER TABLE ssh_keys_temp RENAME TO ssh_keys;`
return db.Exec(renameSQL).Error
}
func v2_lowercaseEmails(db *gorm.DB) error {
// Copy the lowercase emails into the new column
copySQL := `UPDATE users SET email = lower(email);`
return db.Exec(copySQL).Error
}

عرض الملف

@@ -12,6 +12,7 @@ type User struct {
CreatedAt int64
Email string
MD5Hash string // for gravatar, if no Email is specified, the value is random
AvatarURL string
GithubID string
GiteaID string
@@ -81,6 +82,30 @@ func GetUserById(userId uint) (*User, error) {
return user, err
}
func GetUsersFromEmails(emailsSet map[string]struct{}) (map[string]*User, error) {
var users []*User
emails := make([]string, 0, len(emailsSet))
for email := range emailsSet {
emails = append(emails, email)
}
err := db.
Where("email IN ?", emails).
Find(&users).Error
if err != nil {
return nil, err
}
userMap := make(map[string]*User)
for _, user := range users {
userMap[user.Email] = user
}
return userMap, nil
}
func SSHKeyExistsForUser(sshKey string, userId uint) (*SSHKey, error) {
key := new(SSHKey)
err := db.
@@ -135,9 +160,15 @@ func (user *User) HasLiked(gist *Gist) (bool, error) {
func (user *User) DeleteProviderID(provider string) error {
switch provider {
case "github":
return db.Model(&user).Update("github_id", nil).Error
return db.Model(&user).
Update("github_id", nil).
Update("avatar_url", nil).
Error
case "gitea":
return db.Model(&user).Update("gitea_id", nil).Error
return db.Model(&user).
Update("gitea_id", nil).
Update("avatar_url", nil).
Error
}
return nil

عرض الملف

@@ -3,6 +3,7 @@ package web
import (
"context"
"crypto/md5"
"encoding/json"
"errors"
"fmt"
"github.com/labstack/echo/v4"
@@ -139,12 +140,14 @@ func oauthCallback(ctx echo.Context) error {
currUser := getUserLogged(ctx)
if currUser != nil {
// if user is logged in, link account to user
// if user is logged in, link account to user and update its avatar URL
switch user.Provider {
case "github":
currUser.GithubID = user.UserID
currUser.AvatarURL = getAvatarUrlFromProvider("github", user.UserID)
case "gitea":
currUser.GiteaID = user.UserID
currUser.AvatarURL = getAvatarUrlFromProvider("gitea", user.NickName)
}
if err = currUser.Update(); err != nil {
@@ -172,11 +175,14 @@ func oauthCallback(ctx echo.Context) error {
MD5Hash: fmt.Sprintf("%x", md5.Sum([]byte(strings.ToLower(strings.TrimSpace(user.Email))))),
}
// set provider id and avatar URL
switch user.Provider {
case "github":
userDB.GithubID = user.UserID
userDB.AvatarURL = getAvatarUrlFromProvider("github", user.UserID)
case "gitea":
userDB.GiteaID = user.UserID
userDB.AvatarURL = getAvatarUrlFromProvider("gitea", user.NickName)
}
if err = userDB.Create(); err != nil {
@@ -328,3 +334,39 @@ func trimGiteaUrl() string {
return giteaUrl
}
func getAvatarUrlFromProvider(provider string, identifier string) string {
fmt.Println("getAvatarUrlFromProvider", provider, identifier)
switch provider {
case "github":
return "https://avatars.githubusercontent.com/u/" + identifier + "?v=4"
case "gitea":
resp, err := http.Get("https://gitea.com/api/v1/users/" + identifier)
if err != nil {
log.Error().Err(err).Msg("Cannot get user from Gitea")
return ""
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Error().Err(err).Msg("Cannot read Gitea response body")
return ""
}
var result map[string]interface{}
err = json.Unmarshal(body, &result)
if err != nil {
log.Error().Err(err).Msg("Cannot unmarshal Gitea response body")
return ""
}
field, ok := result["avatar_url"]
if !ok {
log.Error().Msg("Field 'avatar_url' not found in Gitea JSON response")
return ""
}
return field.(string)
}
return ""
}

عرض الملف

@@ -186,8 +186,22 @@ func revisions(ctx echo.Context) error {
return errorRes(404, "Page not found", nil)
}
emailsSet := map[string]struct{}{}
for _, commit := range commits {
if commit.AuthorEmail == "" {
continue
}
emailsSet[strings.ToLower(commit.AuthorEmail)] = struct{}{}
}
emailsUsers, err := models.GetUsersFromEmails(emailsSet)
if err != nil {
return errorRes(500, "Error fetching users emails", err)
}
setData(ctx, "page", "revisions")
setData(ctx, "revision", "HEAD")
setData(ctx, "emails", emailsUsers)
setData(ctx, "htmlTitle", "Revision of "+gist.Title)
return html(ctx, "revisions.html")

عرض الملف

@@ -2,7 +2,6 @@ package web
import (
"context"
"crypto/md5"
"encoding/json"
"fmt"
"github.com/gorilla/sessions"
@@ -71,11 +70,16 @@ var fm = template.FuncMap{
"slug": func(s string) string {
return strings.Trim(re.ReplaceAllString(strings.ToLower(s), "-"), "-")
},
"avatarUrl": func(userHash string) string {
return "https://www.gravatar.com/avatar/" + userHash + "?d=identicon&s=200"
},
"emailToMD5": func(email string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(strings.ToLower(strings.TrimSpace(email)))))
"avatarUrl": func(user *models.User, noGravatar bool) string {
if user.AvatarURL != "" {
return user.AvatarURL
}
if user.MD5Hash != "" && !noGravatar {
return "https://www.gravatar.com/avatar/" + user.MD5Hash + "?d=identicon&s=200"
}
return defaultAvatar()
},
"asset": func(jsfile string) string {
if dev {
@@ -83,6 +87,7 @@ var fm = template.FuncMap{
}
return "/" + manifestEntries[jsfile].File
},
"defaultAvatar": defaultAvatar,
}
var EmbedFS fs.FS
@@ -364,3 +369,10 @@ func parseManifestEntries() {
log.Fatal().Err(err).Msg("Failed to unmarshal manifest.json")
}
}
func defaultAvatar() string {
if dev {
return "http://localhost:16157/default.png"
}
return "/" + manifestEntries["default.png"].File
}

عرض الملف

@@ -37,7 +37,7 @@ func emailProcess(ctx echo.Context) error {
hash = fmt.Sprintf("%x", md5.Sum([]byte(strings.ToLower(strings.TrimSpace(email)))))
}
user.Email = email
user.Email = strings.ToLower(email)
user.MD5Hash = hash
if err := user.Update(); err != nil {