From 80f900ebae5c52f736f667a81bbc1ab815344efc Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 25 Feb 2017 22:58:57 +0800 Subject: [PATCH] Fix avatar enumable (#1049) * fix avatar enumable * fix import style --- models/migrations/migrations.go | 2 + models/migrations/v20.go | 66 +++++++++++++++++++++++++++++++++ models/user.go | 8 ++-- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 models/migrations/v20.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 5ae139cb3f..226e548171 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -88,6 +88,8 @@ var migrations = []Migration{ NewMigration("add external login user", addExternalLoginUser), // v19 -> v20 NewMigration("generate and migrate Git hooks", generateAndMigrateGitHooks), + // v20 -> v21 + NewMigration("use new avtar path name for security reason", useNewNameAvatars), } // Migrate database to current version diff --git a/models/migrations/v20.go b/models/migrations/v20.go new file mode 100644 index 0000000000..134a3d51e6 --- /dev/null +++ b/models/migrations/v20.go @@ -0,0 +1,66 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "crypto/md5" + "errors" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" + + "code.gitea.io/gitea/modules/setting" + + "github.com/go-xorm/xorm" +) + +func useNewNameAvatars(x *xorm.Engine) error { + d, err := os.Open(setting.AvatarUploadPath) + if err != nil { + return err + } + names, err := d.Readdirnames(0) + if err != nil { + return err + } + + type User struct { + Avatar string + UseCustomAvatar bool + } + + for _, name := range names { + userID, err := strconv.ParseInt(name, 10, 64) + if err != nil { + return err + } + + var user User + if has, err := x.ID(userID).Get(&user); err != nil { + return err + } else if !has { + return errors.New("Avatar user is not exist") + } + + fPath := filepath.Join(setting.AvatarUploadPath, name) + bs, err := ioutil.ReadFile(fPath) + if err != nil { + return err + } + + user.Avatar = fmt.Sprintf("%x", md5.Sum(bs)) + err = os.Rename(fPath, filepath.Join(setting.AvatarUploadPath, user.Avatar)) + if err != nil { + return err + } + _, err = x.ID(userID).Cols("avatar").Update(&user) + if err != nil { + return err + } + } + return nil +} diff --git a/models/user.go b/models/user.go index 4b019d8d32..e03506c312 100644 --- a/models/user.go +++ b/models/user.go @@ -7,6 +7,7 @@ package models import ( "bytes" "container/list" + "crypto/md5" "crypto/sha256" "crypto/subtle" "encoding/hex" @@ -281,7 +282,7 @@ func (u *User) GenerateActivateCode() string { // CustomAvatarPath returns user custom avatar file path. func (u *User) CustomAvatarPath() string { - return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.ID)) + return filepath.Join(setting.AvatarUploadPath, u.Avatar) } // GenerateRandomAvatar generates a random avatar for user. @@ -326,7 +327,7 @@ func (u *User) RelAvatarLink() string { if !com.IsExist(u.CustomAvatarPath()) { return defaultImgURL } - return setting.AppSubURL + "/avatars/" + com.ToStr(u.ID) + return setting.AppSubURL + "/avatars/" + u.Avatar case setting.DisableGravatar, setting.OfflineMode: if !com.IsExist(u.CustomAvatarPath()) { if err := u.GenerateRandomAvatar(); err != nil { @@ -334,7 +335,7 @@ func (u *User) RelAvatarLink() string { } } - return setting.AppSubURL + "/avatars/" + com.ToStr(u.ID) + return setting.AppSubURL + "/avatars/" + u.Avatar } return base.AvatarLink(u.AvatarEmail) } @@ -425,6 +426,7 @@ func (u *User) UploadAvatar(data []byte) error { } u.UseCustomAvatar = true + u.Avatar = fmt.Sprintf("%x", md5.Sum(data)) if err = updateUser(sess, u); err != nil { return fmt.Errorf("updateUser: %v", err) }