]> source.dussan.org Git - gitea.git/commitdiff
Move user follow and openid into models/user/ (#17613)
authorLunny Xiao <xiaolunwen@gmail.com>
Wed, 17 Nov 2021 09:58:31 +0000 (17:58 +0800)
committerGitHub <noreply@github.com>
Wed, 17 Nov 2021 09:58:31 +0000 (17:58 +0800)
* Move UserRedirect into models/user/

* Fix lint & test

* Fix lint

* Fix lint

* remove nolint comment

* Fix lint

* Move user follow and openid into models/user

* Ignore the lint

* Ignore the lint

* Fix test

* ignore stutters lint on UserOpenID

20 files changed:
.golangci.yml
integrations/delete_user_test.go
models/error.go
models/statistic.go
models/user.go
models/user/follow.go [new file with mode: 0644]
models/user/follow_test.go [new file with mode: 0644]
models/user/main_test.go
models/user/openid.go [new file with mode: 0644]
models/user/openid_test.go [new file with mode: 0644]
models/user_follow.go [deleted file]
models/user_follow_test.go [deleted file]
models/user_openid.go [deleted file]
models/user_openid_test.go [deleted file]
models/user_test.go
routers/api/v1/user/follower.go
routers/web/user/auth_openid.go
routers/web/user/profile.go
routers/web/user/setting/security.go
routers/web/user/setting/security_openid.go

index 1065776a14479a8d1168507c7239c0763069d0d5..9620dcaa356b02413d97861ad236d13434b67eec 100644 (file)
@@ -111,3 +111,6 @@ issues:
       linters:
         - staticcheck
       text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead."
+    - path: models/user/openid.go
+      linters:
+        - golint
index 86896c8ae1208f16c673455ee892b4848dd717ff..f8efab0a24fac32250adebd2702643b559895f41 100644 (file)
@@ -11,12 +11,13 @@ import (
 
        "code.gitea.io/gitea/models"
        "code.gitea.io/gitea/models/unittest"
+       user_model "code.gitea.io/gitea/models/user"
 )
 
 func assertUserDeleted(t *testing.T, userID int64) {
        unittest.AssertNotExistsBean(t, &models.User{ID: userID})
-       unittest.AssertNotExistsBean(t, &models.Follow{UserID: userID})
-       unittest.AssertNotExistsBean(t, &models.Follow{FollowID: userID})
+       unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: userID})
+       unittest.AssertNotExistsBean(t, &user_model.Follow{FollowID: userID})
        unittest.AssertNotExistsBean(t, &models.Repository{OwnerID: userID})
        unittest.AssertNotExistsBean(t, &models.Access{UserID: userID})
        unittest.AssertNotExistsBean(t, &models.OrgUser{UID: userID})
index db0fce0ce1e5ab120c694d0cbcc85c43dcb7d852..7d9b2ae65bc7eabb6f6c29a80cb2a49936cfd258 100644 (file)
@@ -155,21 +155,6 @@ func (err ErrUserInactive) Error() string {
        return fmt.Sprintf("user is inactive [uid: %d, name: %s]", err.UID, err.Name)
 }
 
-// ErrOpenIDAlreadyUsed represents a "OpenIDAlreadyUsed" kind of error.
-type ErrOpenIDAlreadyUsed struct {
-       OpenID string
-}
-
-// IsErrOpenIDAlreadyUsed checks if an error is a ErrOpenIDAlreadyUsed.
-func IsErrOpenIDAlreadyUsed(err error) bool {
-       _, ok := err.(ErrOpenIDAlreadyUsed)
-       return ok
-}
-
-func (err ErrOpenIDAlreadyUsed) Error() string {
-       return fmt.Sprintf("OpenID already in use [oid: %s]", err.OpenID)
-}
-
 // ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
 type ErrUserOwnRepos struct {
        UID int64
index fab35e62dcd4708ef82fad8e13b8ab46e39c8a4c..1849497cd9b46df876b449e993f86dc37b7ea0f2 100644 (file)
@@ -7,6 +7,7 @@ package models
 import (
        "code.gitea.io/gitea/models/db"
        "code.gitea.io/gitea/models/login"
+       user_model "code.gitea.io/gitea/models/user"
        "code.gitea.io/gitea/models/webhook"
        "code.gitea.io/gitea/modules/setting"
 )
@@ -92,7 +93,7 @@ func GetStatistic() (stats Statistic) {
 
        stats.Counter.Comment, _ = e.Count(new(Comment))
        stats.Counter.Oauth = 0
-       stats.Counter.Follow, _ = e.Count(new(Follow))
+       stats.Counter.Follow, _ = e.Count(new(user_model.Follow))
        stats.Counter.Mirror, _ = e.Count(new(Mirror))
        stats.Counter.Release, _ = e.Count(new(Release))
        stats.Counter.LoginSource = login.CountSources()
index 8146c184e70a3d3001f70c054fad9c26cca743b5..e3cf94efe0cd2afbf3d56b7683b81f9d46ca3681 100644 (file)
@@ -25,6 +25,7 @@ import (
        "code.gitea.io/gitea/models/login"
        "code.gitea.io/gitea/models/unit"
        user_model "code.gitea.io/gitea/models/user"
+       "code.gitea.io/gitea/modules/auth/openid"
        "code.gitea.io/gitea/modules/base"
        "code.gitea.io/gitea/modules/git"
        "code.gitea.io/gitea/modules/log"
@@ -359,7 +360,7 @@ func (u *User) GetFollowers(listOptions db.ListOptions) ([]*User, error) {
 
 // IsFollowing returns true if user is following followID.
 func (u *User) IsFollowing(followID int64) bool {
-       return IsFollowing(u.ID, followID)
+       return user_model.IsFollowing(u.ID, followID)
 }
 
 // GetFollowing returns range of user's following.
@@ -469,7 +470,7 @@ func (u *User) isVisibleToUser(e db.Engine, viewer *User) bool {
                }
 
                // If they follow - they see each over
-               follower := IsFollowing(u.ID, viewer.ID)
+               follower := user_model.IsFollowing(u.ID, viewer.ID)
                if follower {
                        return true
                }
@@ -1212,12 +1213,12 @@ func deleteUser(e db.Engine, u *User) error {
                &Access{UserID: u.ID},
                &Watch{UserID: u.ID},
                &Star{UID: u.ID},
-               &Follow{UserID: u.ID},
-               &Follow{FollowID: u.ID},
+               &user_model.Follow{UserID: u.ID},
+               &user_model.Follow{FollowID: u.ID},
                &Action{UserID: u.ID},
                &IssueUser{UID: u.ID},
                &user_model.EmailAddress{UID: u.ID},
-               &UserOpenID{UID: u.ID},
+               &user_model.UserOpenID{UID: u.ID},
                &Reaction{UserID: u.ID},
                &TeamUser{UID: u.ID},
                &Collaboration{UserID: u.ID},
@@ -1798,3 +1799,29 @@ func IterateUser(f func(user *User) error) error {
                }
        }
 }
+
+// GetUserByOpenID returns the user object by given OpenID if exists.
+func GetUserByOpenID(uri string) (*User, error) {
+       if len(uri) == 0 {
+               return nil, ErrUserNotExist{0, uri, 0}
+       }
+
+       uri, err := openid.Normalize(uri)
+       if err != nil {
+               return nil, err
+       }
+
+       log.Trace("Normalized OpenID URI: " + uri)
+
+       // Otherwise, check in openid table
+       oid := &user_model.UserOpenID{}
+       has, err := db.GetEngine(db.DefaultContext).Where("uri=?", uri).Get(oid)
+       if err != nil {
+               return nil, err
+       }
+       if has {
+               return GetUserByID(oid.UID)
+       }
+
+       return nil, ErrUserNotExist{0, uri, 0}
+}
diff --git a/models/user/follow.go b/models/user/follow.go
new file mode 100644 (file)
index 0000000..89675b5
--- /dev/null
@@ -0,0 +1,80 @@
+// 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 user
+
+import (
+       "code.gitea.io/gitea/models/db"
+       "code.gitea.io/gitea/modules/timeutil"
+)
+
+// Follow represents relations of user and his/her followers.
+type Follow struct {
+       ID          int64              `xorm:"pk autoincr"`
+       UserID      int64              `xorm:"UNIQUE(follow)"`
+       FollowID    int64              `xorm:"UNIQUE(follow)"`
+       CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+}
+
+func init() {
+       db.RegisterModel(new(Follow))
+}
+
+// IsFollowing returns true if user is following followID.
+func IsFollowing(userID, followID int64) bool {
+       has, _ := db.GetEngine(db.DefaultContext).Get(&Follow{UserID: userID, FollowID: followID})
+       return has
+}
+
+// FollowUser marks someone be another's follower.
+func FollowUser(userID, followID int64) (err error) {
+       if userID == followID || IsFollowing(userID, followID) {
+               return nil
+       }
+
+       sess := db.NewSession(db.DefaultContext)
+       defer sess.Close()
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if _, err = sess.Insert(&Follow{UserID: userID, FollowID: followID}); err != nil {
+               return err
+       }
+
+       if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?", followID); err != nil {
+               return err
+       }
+
+       if _, err = sess.Exec("UPDATE `user` SET num_following = num_following + 1 WHERE id = ?", userID); err != nil {
+               return err
+       }
+       return sess.Commit()
+}
+
+// UnfollowUser unmarks someone as another's follower.
+func UnfollowUser(userID, followID int64) (err error) {
+       if userID == followID || !IsFollowing(userID, followID) {
+               return nil
+       }
+
+       sess := db.NewSession(db.DefaultContext)
+       defer sess.Close()
+       if err = sess.Begin(); err != nil {
+               return err
+       }
+
+       if _, err = sess.Delete(&Follow{UserID: userID, FollowID: followID}); err != nil {
+               return err
+       }
+
+       if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers - 1 WHERE id = ?", followID); err != nil {
+               return err
+       }
+
+       if _, err = sess.Exec("UPDATE `user` SET num_following = num_following - 1 WHERE id = ?", userID); err != nil {
+               return err
+       }
+       return sess.Commit()
+}
diff --git a/models/user/follow_test.go b/models/user/follow_test.go
new file mode 100644 (file)
index 0000000..538c7b1
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2020 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 user
+
+import (
+       "testing"
+
+       "code.gitea.io/gitea/models/unittest"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestIsFollowing(t *testing.T) {
+       assert.NoError(t, unittest.PrepareTestDatabase())
+       assert.True(t, IsFollowing(4, 2))
+       assert.False(t, IsFollowing(2, 4))
+       assert.False(t, IsFollowing(5, unittest.NonexistentID))
+       assert.False(t, IsFollowing(unittest.NonexistentID, 5))
+       assert.False(t, IsFollowing(unittest.NonexistentID, unittest.NonexistentID))
+}
index 1dd9fb278131ac5882b0536680f2a27c633e29ca..7862556a03872ee2e89ae104940ba37bad336e13 100644 (file)
@@ -15,5 +15,7 @@ func TestMain(m *testing.M) {
        unittest.MainTest(m, filepath.Join("..", ".."),
                "email_address.yml",
                "user_redirect.yml",
+               "follow.yml",
+               "user_open_id.yml",
        )
 }
diff --git a/models/user/openid.go b/models/user/openid.go
new file mode 100644 (file)
index 0000000..8ca3c7f
--- /dev/null
@@ -0,0 +1,112 @@
+// 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 user
+
+import (
+       "errors"
+       "fmt"
+
+       "code.gitea.io/gitea/models/db"
+)
+
+// ErrOpenIDNotExist openid is not known
+var ErrOpenIDNotExist = errors.New("OpenID is unknown")
+
+// UserOpenID is the list of all OpenID identities of a user.
+// Since this is a middle table, name it OpenID is not suitable, so we ignore the lint here
+type UserOpenID struct { //revive:disable-line:exported
+       ID   int64  `xorm:"pk autoincr"`
+       UID  int64  `xorm:"INDEX NOT NULL"`
+       URI  string `xorm:"UNIQUE NOT NULL"`
+       Show bool   `xorm:"DEFAULT false"`
+}
+
+func init() {
+       db.RegisterModel(new(UserOpenID))
+}
+
+// GetUserOpenIDs returns all openid addresses that belongs to given user.
+func GetUserOpenIDs(uid int64) ([]*UserOpenID, error) {
+       openids := make([]*UserOpenID, 0, 5)
+       if err := db.GetEngine(db.DefaultContext).
+               Where("uid=?", uid).
+               Asc("id").
+               Find(&openids); err != nil {
+               return nil, err
+       }
+
+       return openids, nil
+}
+
+// isOpenIDUsed returns true if the openid has been used.
+func isOpenIDUsed(e db.Engine, uri string) (bool, error) {
+       if len(uri) == 0 {
+               return true, nil
+       }
+
+       return e.Get(&UserOpenID{URI: uri})
+}
+
+// ErrOpenIDAlreadyUsed represents a "OpenIDAlreadyUsed" kind of error.
+type ErrOpenIDAlreadyUsed struct {
+       OpenID string
+}
+
+// IsErrOpenIDAlreadyUsed checks if an error is a ErrOpenIDAlreadyUsed.
+func IsErrOpenIDAlreadyUsed(err error) bool {
+       _, ok := err.(ErrOpenIDAlreadyUsed)
+       return ok
+}
+
+func (err ErrOpenIDAlreadyUsed) Error() string {
+       return fmt.Sprintf("OpenID already in use [oid: %s]", err.OpenID)
+}
+
+// NOTE: make sure openid.URI is normalized already
+func addUserOpenID(e db.Engine, openid *UserOpenID) error {
+       used, err := isOpenIDUsed(e, openid.URI)
+       if err != nil {
+               return err
+       } else if used {
+               return ErrOpenIDAlreadyUsed{openid.URI}
+       }
+
+       _, err = e.Insert(openid)
+       return err
+}
+
+// AddUserOpenID adds an pre-verified/normalized OpenID URI to given user.
+func AddUserOpenID(openid *UserOpenID) error {
+       return addUserOpenID(db.GetEngine(db.DefaultContext), openid)
+}
+
+// DeleteUserOpenID deletes an openid address of given user.
+func DeleteUserOpenID(openid *UserOpenID) (err error) {
+       var deleted int64
+       // ask to check UID
+       address := UserOpenID{
+               UID: openid.UID,
+       }
+       if openid.ID > 0 {
+               deleted, err = db.GetEngine(db.DefaultContext).ID(openid.ID).Delete(&address)
+       } else {
+               deleted, err = db.GetEngine(db.DefaultContext).
+                       Where("openid=?", openid.URI).
+                       Delete(&address)
+       }
+
+       if err != nil {
+               return err
+       } else if deleted != 1 {
+               return ErrOpenIDNotExist
+       }
+       return nil
+}
+
+// ToggleUserOpenIDVisibility toggles visibility of an openid address of given user.
+func ToggleUserOpenIDVisibility(id int64) (err error) {
+       _, err = db.GetEngine(db.DefaultContext).Exec("update `user_open_id` set `show` = not `show` where `id` = ?", id)
+       return err
+}
diff --git a/models/user/openid_test.go b/models/user/openid_test.go
new file mode 100644 (file)
index 0000000..ba678ef
--- /dev/null
@@ -0,0 +1,63 @@
+// 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 user
+
+import (
+       "testing"
+
+       "code.gitea.io/gitea/models/unittest"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestGetUserOpenIDs(t *testing.T) {
+       assert.NoError(t, unittest.PrepareTestDatabase())
+
+       oids, err := GetUserOpenIDs(int64(1))
+       if assert.NoError(t, err) && assert.Len(t, oids, 2) {
+               assert.Equal(t, "https://user1.domain1.tld/", oids[0].URI)
+               assert.False(t, oids[0].Show)
+               assert.Equal(t, "http://user1.domain2.tld/", oids[1].URI)
+               assert.True(t, oids[1].Show)
+       }
+
+       oids, err = GetUserOpenIDs(int64(2))
+       if assert.NoError(t, err) && assert.Len(t, oids, 1) {
+               assert.Equal(t, "https://domain1.tld/user2/", oids[0].URI)
+               assert.True(t, oids[0].Show)
+       }
+}
+
+func TestToggleUserOpenIDVisibility(t *testing.T) {
+       assert.NoError(t, unittest.PrepareTestDatabase())
+       oids, err := GetUserOpenIDs(int64(2))
+       if !assert.NoError(t, err) || !assert.Len(t, oids, 1) {
+               return
+       }
+       assert.True(t, oids[0].Show)
+
+       err = ToggleUserOpenIDVisibility(oids[0].ID)
+       if !assert.NoError(t, err) {
+               return
+       }
+
+       oids, err = GetUserOpenIDs(int64(2))
+       if !assert.NoError(t, err) || !assert.Len(t, oids, 1) {
+               return
+       }
+       assert.False(t, oids[0].Show)
+       err = ToggleUserOpenIDVisibility(oids[0].ID)
+       if !assert.NoError(t, err) {
+               return
+       }
+
+       oids, err = GetUserOpenIDs(int64(2))
+       if !assert.NoError(t, err) {
+               return
+       }
+       if assert.Len(t, oids, 1) {
+               assert.True(t, oids[0].Show)
+       }
+}
diff --git a/models/user_follow.go b/models/user_follow.go
deleted file mode 100644 (file)
index 8832aa2..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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 models
-
-import (
-       "code.gitea.io/gitea/models/db"
-       "code.gitea.io/gitea/modules/timeutil"
-)
-
-// Follow represents relations of user and his/her followers.
-type Follow struct {
-       ID          int64              `xorm:"pk autoincr"`
-       UserID      int64              `xorm:"UNIQUE(follow)"`
-       FollowID    int64              `xorm:"UNIQUE(follow)"`
-       CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
-}
-
-func init() {
-       db.RegisterModel(new(Follow))
-}
-
-// IsFollowing returns true if user is following followID.
-func IsFollowing(userID, followID int64) bool {
-       has, _ := db.GetEngine(db.DefaultContext).Get(&Follow{UserID: userID, FollowID: followID})
-       return has
-}
-
-// FollowUser marks someone be another's follower.
-func FollowUser(userID, followID int64) (err error) {
-       if userID == followID || IsFollowing(userID, followID) {
-               return nil
-       }
-
-       sess := db.NewSession(db.DefaultContext)
-       defer sess.Close()
-       if err = sess.Begin(); err != nil {
-               return err
-       }
-
-       if _, err = sess.Insert(&Follow{UserID: userID, FollowID: followID}); err != nil {
-               return err
-       }
-
-       if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?", followID); err != nil {
-               return err
-       }
-
-       if _, err = sess.Exec("UPDATE `user` SET num_following = num_following + 1 WHERE id = ?", userID); err != nil {
-               return err
-       }
-       return sess.Commit()
-}
-
-// UnfollowUser unmarks someone as another's follower.
-func UnfollowUser(userID, followID int64) (err error) {
-       if userID == followID || !IsFollowing(userID, followID) {
-               return nil
-       }
-
-       sess := db.NewSession(db.DefaultContext)
-       defer sess.Close()
-       if err = sess.Begin(); err != nil {
-               return err
-       }
-
-       if _, err = sess.Delete(&Follow{UserID: userID, FollowID: followID}); err != nil {
-               return err
-       }
-
-       if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers - 1 WHERE id = ?", followID); err != nil {
-               return err
-       }
-
-       if _, err = sess.Exec("UPDATE `user` SET num_following = num_following - 1 WHERE id = ?", userID); err != nil {
-               return err
-       }
-       return sess.Commit()
-}
diff --git a/models/user_follow_test.go b/models/user_follow_test.go
deleted file mode 100644 (file)
index 5ba9227..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 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 models
-
-import (
-       "testing"
-
-       "code.gitea.io/gitea/models/unittest"
-       "github.com/stretchr/testify/assert"
-)
-
-func TestIsFollowing(t *testing.T) {
-       assert.NoError(t, unittest.PrepareTestDatabase())
-       assert.True(t, IsFollowing(4, 2))
-       assert.False(t, IsFollowing(2, 4))
-       assert.False(t, IsFollowing(5, unittest.NonexistentID))
-       assert.False(t, IsFollowing(unittest.NonexistentID, 5))
-       assert.False(t, IsFollowing(unittest.NonexistentID, unittest.NonexistentID))
-}
-
-func TestFollowUser(t *testing.T) {
-       assert.NoError(t, unittest.PrepareTestDatabase())
-
-       testSuccess := func(followerID, followedID int64) {
-               assert.NoError(t, FollowUser(followerID, followedID))
-               unittest.AssertExistsAndLoadBean(t, &Follow{UserID: followerID, FollowID: followedID})
-       }
-       testSuccess(4, 2)
-       testSuccess(5, 2)
-
-       assert.NoError(t, FollowUser(2, 2))
-
-       unittest.CheckConsistencyFor(t, &User{})
-}
-
-func TestUnfollowUser(t *testing.T) {
-       assert.NoError(t, unittest.PrepareTestDatabase())
-
-       testSuccess := func(followerID, followedID int64) {
-               assert.NoError(t, UnfollowUser(followerID, followedID))
-               unittest.AssertNotExistsBean(t, &Follow{UserID: followerID, FollowID: followedID})
-       }
-       testSuccess(4, 2)
-       testSuccess(5, 2)
-       testSuccess(2, 2)
-
-       unittest.CheckConsistencyFor(t, &User{})
-}
diff --git a/models/user_openid.go b/models/user_openid.go
deleted file mode 100644 (file)
index 17a5853..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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 models
-
-import (
-       "errors"
-
-       "code.gitea.io/gitea/models/db"
-       "code.gitea.io/gitea/modules/auth/openid"
-       "code.gitea.io/gitea/modules/log"
-)
-
-// ErrOpenIDNotExist openid is not known
-var ErrOpenIDNotExist = errors.New("OpenID is unknown")
-
-// UserOpenID is the list of all OpenID identities of a user.
-type UserOpenID struct {
-       ID   int64  `xorm:"pk autoincr"`
-       UID  int64  `xorm:"INDEX NOT NULL"`
-       URI  string `xorm:"UNIQUE NOT NULL"`
-       Show bool   `xorm:"DEFAULT false"`
-}
-
-func init() {
-       db.RegisterModel(new(UserOpenID))
-}
-
-// GetUserOpenIDs returns all openid addresses that belongs to given user.
-func GetUserOpenIDs(uid int64) ([]*UserOpenID, error) {
-       openids := make([]*UserOpenID, 0, 5)
-       if err := db.GetEngine(db.DefaultContext).
-               Where("uid=?", uid).
-               Asc("id").
-               Find(&openids); err != nil {
-               return nil, err
-       }
-
-       return openids, nil
-}
-
-// isOpenIDUsed returns true if the openid has been used.
-func isOpenIDUsed(e db.Engine, uri string) (bool, error) {
-       if len(uri) == 0 {
-               return true, nil
-       }
-
-       return e.Get(&UserOpenID{URI: uri})
-}
-
-// NOTE: make sure openid.URI is normalized already
-func addUserOpenID(e db.Engine, openid *UserOpenID) error {
-       used, err := isOpenIDUsed(e, openid.URI)
-       if err != nil {
-               return err
-       } else if used {
-               return ErrOpenIDAlreadyUsed{openid.URI}
-       }
-
-       _, err = e.Insert(openid)
-       return err
-}
-
-// AddUserOpenID adds an pre-verified/normalized OpenID URI to given user.
-func AddUserOpenID(openid *UserOpenID) error {
-       return addUserOpenID(db.GetEngine(db.DefaultContext), openid)
-}
-
-// DeleteUserOpenID deletes an openid address of given user.
-func DeleteUserOpenID(openid *UserOpenID) (err error) {
-       var deleted int64
-       // ask to check UID
-       address := UserOpenID{
-               UID: openid.UID,
-       }
-       if openid.ID > 0 {
-               deleted, err = db.GetEngine(db.DefaultContext).ID(openid.ID).Delete(&address)
-       } else {
-               deleted, err = db.GetEngine(db.DefaultContext).
-                       Where("openid=?", openid.URI).
-                       Delete(&address)
-       }
-
-       if err != nil {
-               return err
-       } else if deleted != 1 {
-               return ErrOpenIDNotExist
-       }
-       return nil
-}
-
-// ToggleUserOpenIDVisibility toggles visibility of an openid address of given user.
-func ToggleUserOpenIDVisibility(id int64) (err error) {
-       _, err = db.GetEngine(db.DefaultContext).Exec("update `user_open_id` set `show` = not `show` where `id` = ?", id)
-       return err
-}
-
-// GetUserByOpenID returns the user object by given OpenID if exists.
-func GetUserByOpenID(uri string) (*User, error) {
-       if len(uri) == 0 {
-               return nil, ErrUserNotExist{0, uri, 0}
-       }
-
-       uri, err := openid.Normalize(uri)
-       if err != nil {
-               return nil, err
-       }
-
-       log.Trace("Normalized OpenID URI: " + uri)
-
-       // Otherwise, check in openid table
-       oid := &UserOpenID{}
-       has, err := db.GetEngine(db.DefaultContext).Where("uri=?", uri).Get(oid)
-       if err != nil {
-               return nil, err
-       }
-       if has {
-               return GetUserByID(oid.UID)
-       }
-
-       return nil, ErrUserNotExist{0, uri, 0}
-}
diff --git a/models/user_openid_test.go b/models/user_openid_test.go
deleted file mode 100644 (file)
index d0d801a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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 models
-
-import (
-       "testing"
-
-       "code.gitea.io/gitea/models/unittest"
-
-       "github.com/stretchr/testify/assert"
-)
-
-func TestGetUserOpenIDs(t *testing.T) {
-       assert.NoError(t, unittest.PrepareTestDatabase())
-
-       oids, err := GetUserOpenIDs(int64(1))
-       if assert.NoError(t, err) && assert.Len(t, oids, 2) {
-               assert.Equal(t, "https://user1.domain1.tld/", oids[0].URI)
-               assert.False(t, oids[0].Show)
-               assert.Equal(t, "http://user1.domain2.tld/", oids[1].URI)
-               assert.True(t, oids[1].Show)
-       }
-
-       oids, err = GetUserOpenIDs(int64(2))
-       if assert.NoError(t, err) && assert.Len(t, oids, 1) {
-               assert.Equal(t, "https://domain1.tld/user2/", oids[0].URI)
-               assert.True(t, oids[0].Show)
-       }
-}
-
-func TestGetUserByOpenID(t *testing.T) {
-       assert.NoError(t, unittest.PrepareTestDatabase())
-
-       _, err := GetUserByOpenID("https://unknown")
-       if assert.Error(t, err) {
-               assert.True(t, IsErrUserNotExist(err))
-       }
-
-       user, err := GetUserByOpenID("https://user1.domain1.tld")
-       if assert.NoError(t, err) {
-               assert.Equal(t, int64(1), user.ID)
-       }
-
-       user, err = GetUserByOpenID("https://domain1.tld/user2/")
-       if assert.NoError(t, err) {
-               assert.Equal(t, int64(2), user.ID)
-       }
-}
-
-func TestToggleUserOpenIDVisibility(t *testing.T) {
-       assert.NoError(t, unittest.PrepareTestDatabase())
-       oids, err := GetUserOpenIDs(int64(2))
-       if !assert.NoError(t, err) || !assert.Len(t, oids, 1) {
-               return
-       }
-       assert.True(t, oids[0].Show)
-
-       err = ToggleUserOpenIDVisibility(oids[0].ID)
-       if !assert.NoError(t, err) {
-               return
-       }
-
-       oids, err = GetUserOpenIDs(int64(2))
-       if !assert.NoError(t, err) || !assert.Len(t, oids, 1) {
-               return
-       }
-       assert.False(t, oids[0].Show)
-       err = ToggleUserOpenIDVisibility(oids[0].ID)
-       if !assert.NoError(t, err) {
-               return
-       }
-
-       oids, err = GetUserOpenIDs(int64(2))
-       if !assert.NoError(t, err) {
-               return
-       }
-       if assert.Len(t, oids, 1) {
-               assert.True(t, oids[0].Show)
-       }
-}
index dc273ce1bcd159f5d969024292912ad25d13d31f..4e2e5217673b4bffd17272b9b93cab3cc8a829df 100644 (file)
@@ -560,3 +560,51 @@ func TestNewUserRedirect3(t *testing.T) {
                RedirectUserID: user.ID,
        })
 }
+
+func TestFollowUser(t *testing.T) {
+       assert.NoError(t, unittest.PrepareTestDatabase())
+
+       testSuccess := func(followerID, followedID int64) {
+               assert.NoError(t, user_model.FollowUser(followerID, followedID))
+               unittest.AssertExistsAndLoadBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
+       }
+       testSuccess(4, 2)
+       testSuccess(5, 2)
+
+       assert.NoError(t, user_model.FollowUser(2, 2))
+
+       unittest.CheckConsistencyFor(t, &User{})
+}
+
+func TestUnfollowUser(t *testing.T) {
+       assert.NoError(t, unittest.PrepareTestDatabase())
+
+       testSuccess := func(followerID, followedID int64) {
+               assert.NoError(t, user_model.UnfollowUser(followerID, followedID))
+               unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
+       }
+       testSuccess(4, 2)
+       testSuccess(5, 2)
+       testSuccess(2, 2)
+
+       unittest.CheckConsistencyFor(t, &User{})
+}
+
+func TestGetUserByOpenID(t *testing.T) {
+       assert.NoError(t, unittest.PrepareTestDatabase())
+
+       _, err := GetUserByOpenID("https://unknown")
+       if assert.Error(t, err) {
+               assert.True(t, IsErrUserNotExist(err))
+       }
+
+       user, err := GetUserByOpenID("https://user1.domain1.tld")
+       if assert.NoError(t, err) {
+               assert.Equal(t, int64(1), user.ID)
+       }
+
+       user, err = GetUserByOpenID("https://domain1.tld/user2/")
+       if assert.NoError(t, err) {
+               assert.Equal(t, int64(2), user.ID)
+       }
+}
index e273ac6a0207145a1130aec0c1877f5b54a6fef1..5d66f3bcc357c8dbbf6875fa9eabd3d4963cfa6e 100644 (file)
@@ -9,6 +9,7 @@ import (
        "net/http"
 
        "code.gitea.io/gitea/models"
+       user_model "code.gitea.io/gitea/models/user"
        "code.gitea.io/gitea/modules/context"
        "code.gitea.io/gitea/modules/convert"
        api "code.gitea.io/gitea/modules/structs"
@@ -239,7 +240,7 @@ func Follow(ctx *context.APIContext) {
        if ctx.Written() {
                return
        }
-       if err := models.FollowUser(ctx.User.ID, target.ID); err != nil {
+       if err := user_model.FollowUser(ctx.User.ID, target.ID); err != nil {
                ctx.Error(http.StatusInternalServerError, "FollowUser", err)
                return
        }
@@ -265,7 +266,7 @@ func Unfollow(ctx *context.APIContext) {
        if ctx.Written() {
                return
        }
-       if err := models.UnfollowUser(ctx.User.ID, target.ID); err != nil {
+       if err := user_model.UnfollowUser(ctx.User.ID, target.ID); err != nil {
                ctx.Error(http.StatusInternalServerError, "UnfollowUser", err)
                return
        }
index e6ad6fef4c413d8d49fca2cf4a22979cc864f760..4724a7b431fc73587eff0633a9d1fc71ef72dd5a 100644 (file)
@@ -10,6 +10,7 @@ import (
        "net/url"
 
        "code.gitea.io/gitea/models"
+       user_model "code.gitea.io/gitea/models/user"
        "code.gitea.io/gitea/modules/auth/openid"
        "code.gitea.io/gitea/modules/base"
        "code.gitea.io/gitea/modules/context"
@@ -302,9 +303,9 @@ func ConnectOpenIDPost(ctx *context.Context) {
        }
 
        // add OpenID for the user
-       userOID := &models.UserOpenID{UID: u.ID, URI: oid}
-       if err = models.AddUserOpenID(userOID); err != nil {
-               if models.IsErrOpenIDAlreadyUsed(err) {
+       userOID := &user_model.UserOpenID{UID: u.ID, URI: oid}
+       if err = user_model.AddUserOpenID(userOID); err != nil {
+               if user_model.IsErrOpenIDAlreadyUsed(err) {
                        ctx.RenderWithErr(ctx.Tr("form.openid_been_used", oid), tplConnectOID, &form)
                        return
                }
@@ -430,9 +431,9 @@ func RegisterOpenIDPost(ctx *context.Context) {
        }
 
        // add OpenID for the user
-       userOID := &models.UserOpenID{UID: u.ID, URI: oid}
-       if err = models.AddUserOpenID(userOID); err != nil {
-               if models.IsErrOpenIDAlreadyUsed(err) {
+       userOID := &user_model.UserOpenID{UID: u.ID, URI: oid}
+       if err = user_model.AddUserOpenID(userOID); err != nil {
+               if user_model.IsErrOpenIDAlreadyUsed(err) {
                        ctx.RenderWithErr(ctx.Tr("form.openid_been_used", oid), tplSignUpOID, &form)
                        return
                }
index 17c4783c694c7e24440cc30fec781264799ea1d0..72d36761da8ce28616a769a1884f8464faf2192b 100644 (file)
@@ -131,7 +131,7 @@ func Profile(ctx *context.Context) {
        }
 
        // Show OpenID URIs
-       openIDs, err := models.GetUserOpenIDs(ctxUser.ID)
+       openIDs, err := user_model.GetUserOpenIDs(ctxUser.ID)
        if err != nil {
                ctx.ServerError("GetUserOpenIDs", err)
                return
@@ -355,9 +355,9 @@ func Action(ctx *context.Context) {
        var err error
        switch ctx.Params(":action") {
        case "follow":
-               err = models.FollowUser(ctx.User.ID, u.ID)
+               err = user_model.FollowUser(ctx.User.ID, u.ID)
        case "unfollow":
-               err = models.UnfollowUser(ctx.User.ID, u.ID)
+               err = user_model.UnfollowUser(ctx.User.ID, u.ID)
        }
 
        if err != nil {
index 65e9790d47725b1cbc872de738b481b4662480fb..f0b1d8232af5374290fda0793629e1aa0cb98d3a 100644 (file)
@@ -10,6 +10,7 @@ import (
 
        "code.gitea.io/gitea/models"
        "code.gitea.io/gitea/models/login"
+       user_model "code.gitea.io/gitea/models/user"
        "code.gitea.io/gitea/modules/base"
        "code.gitea.io/gitea/modules/context"
        "code.gitea.io/gitea/modules/setting"
@@ -107,7 +108,7 @@ func loadSecurityData(ctx *context.Context) {
        }
        ctx.Data["AccountLinks"] = sources
 
-       openid, err := models.GetUserOpenIDs(ctx.User.ID)
+       openid, err := user_model.GetUserOpenIDs(ctx.User.ID)
        if err != nil {
                ctx.ServerError("GetUserOpenIDs", err)
                return
index 8bb932805cc2c5408a1873c1ac0d39c4122b48fb..9cdda79b92edb7ee87779d05c178b2c1a98a019a 100644 (file)
@@ -7,7 +7,7 @@ package setting
 import (
        "net/http"
 
-       "code.gitea.io/gitea/models"
+       user_model "code.gitea.io/gitea/models/user"
        "code.gitea.io/gitea/modules/auth/openid"
        "code.gitea.io/gitea/modules/context"
        "code.gitea.io/gitea/modules/log"
@@ -45,7 +45,7 @@ func OpenIDPost(ctx *context.Context) {
        form.Openid = id
        log.Trace("Normalized id: " + id)
 
-       oids, err := models.GetUserOpenIDs(ctx.User.ID)
+       oids, err := user_model.GetUserOpenIDs(ctx.User.ID)
        if err != nil {
                ctx.ServerError("GetUserOpenIDs", err)
                return
@@ -89,9 +89,9 @@ func settingsOpenIDVerify(ctx *context.Context) {
 
        log.Trace("Verified ID: " + id)
 
-       oid := &models.UserOpenID{UID: ctx.User.ID, URI: id}
-       if err = models.AddUserOpenID(oid); err != nil {
-               if models.IsErrOpenIDAlreadyUsed(err) {
+       oid := &user_model.UserOpenID{UID: ctx.User.ID, URI: id}
+       if err = user_model.AddUserOpenID(oid); err != nil {
+               if user_model.IsErrOpenIDAlreadyUsed(err) {
                        ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsSecurity, &forms.AddOpenIDForm{Openid: id})
                        return
                }
@@ -106,7 +106,7 @@ func settingsOpenIDVerify(ctx *context.Context) {
 
 // DeleteOpenID response for delete user's openid
 func DeleteOpenID(ctx *context.Context) {
-       if err := models.DeleteUserOpenID(&models.UserOpenID{ID: ctx.FormInt64("id"), UID: ctx.User.ID}); err != nil {
+       if err := user_model.DeleteUserOpenID(&user_model.UserOpenID{ID: ctx.FormInt64("id"), UID: ctx.User.ID}); err != nil {
                ctx.ServerError("DeleteUserOpenID", err)
                return
        }
@@ -120,7 +120,7 @@ func DeleteOpenID(ctx *context.Context) {
 
 // ToggleOpenIDVisibility response for toggle visibility of user's openid
 func ToggleOpenIDVisibility(ctx *context.Context) {
-       if err := models.ToggleUserOpenIDVisibility(ctx.FormInt64("id")); err != nil {
+       if err := user_model.ToggleUserOpenIDVisibility(ctx.FormInt64("id")); err != nil {
                ctx.ServerError("ToggleUserOpenIDVisibility", err)
                return
        }