Skip to content

Commit

Permalink
all: unwrap database.UsersStore interface (#7708)
Browse files Browse the repository at this point in the history
  • Loading branch information
unknwon committed Mar 28, 2024
1 parent 2020128 commit d9ecdca
Show file tree
Hide file tree
Showing 62 changed files with 1,241 additions and 4,218 deletions.
4 changes: 2 additions & 2 deletions internal/cmd/admin.go
Expand Up @@ -52,7 +52,7 @@ to make automatic initialization process more smoothly`,
Name: "delete-inactive-users",
Usage: "Delete all inactive accounts",
Action: adminDashboardOperation(
func() error { return database.Users.DeleteInactivated() },
func() error { return database.Handle.Users().DeleteInactivated() },
"All inactivated accounts have been deleted successfully",
),
Flags: []cli.Flag{
Expand Down Expand Up @@ -152,7 +152,7 @@ func runCreateUser(c *cli.Context) error {
return errors.Wrap(err, "set engine")
}

user, err := database.Users.Create(
user, err := database.Handle.Users().Create(
context.Background(),
c.String("name"),
c.String("email"),
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/serv.go
Expand Up @@ -162,7 +162,7 @@ func runServ(c *cli.Context) error {
repoName := strings.TrimSuffix(strings.ToLower(repoFields[1]), ".git")
repoName = strings.TrimSuffix(repoName, ".wiki")

owner, err := database.Users.GetByUsername(ctx, ownerName)
owner, err := database.Handle.Users().GetByUsername(ctx, ownerName)
if err != nil {
if database.IsErrUserNotExist(err) {
fail("Repository owner does not exist", "Unregistered owner: %s", ownerName)
Expand Down Expand Up @@ -205,7 +205,7 @@ func runServ(c *cli.Context) error {
}
checkDeployKey(key, repo)
} else {
user, err = database.Users.GetByKeyID(ctx, key.ID)
user, err = database.Handle.Users().GetByKeyID(ctx, key.ID)
if err != nil {
fail("Internal error", "Failed to get user by key ID '%d': %v", key.ID, err)
}
Expand Down
38 changes: 32 additions & 6 deletions internal/context/auth.go
Expand Up @@ -113,6 +113,32 @@ type AuthStore interface {
// TouchAccessTokenByID updates the updated time of the given access token to
// the current time.
TouchAccessTokenByID(ctx context.Context, id int64) error

// GetUserByID returns the user with given ID. It returns
// database.ErrUserNotExist when not found.
GetUserByID(ctx context.Context, id int64) (*database.User, error)
// GetUserByUsername returns the user with given username. It returns
// database.ErrUserNotExist when not found.
GetUserByUsername(ctx context.Context, username string) (*database.User, error)
// CreateUser creates a new user and persists to database. It returns
// database.ErrNameNotAllowed if the given name or pattern of the name is not
// allowed as a username, or database.ErrUserAlreadyExist when a user with same
// name already exists, or database.ErrEmailAlreadyUsed if the email has been
// verified by another user.
CreateUser(ctx context.Context, username, email string, opts database.CreateUserOptions) (*database.User, error)
// AuthenticateUser validates username and password via given login source ID.
// It returns database.ErrUserNotExist when the user was not found.
//
// When the "loginSourceID" is negative, it aborts the process and returns
// database.ErrUserNotExist if the user was not found in the database.
//
// When the "loginSourceID" is non-negative, it returns
// database.ErrLoginSourceMismatch if the user has different login source ID
// than the "loginSourceID".
//
// When the "loginSourceID" is positive, it tries to authenticate via given
// login source and creates a new user when not yet exists in the database.
AuthenticateUser(ctx context.Context, login, password string, loginSourceID int64) (*database.User, error)
}

// authenticatedUserID returns the ID of the authenticated user, along with a bool value
Expand Down Expand Up @@ -160,7 +186,7 @@ func authenticatedUserID(store AuthStore, c *macaron.Context, sess session.Store
return 0, false
}
if id, ok := uid.(int64); ok {
_, err := database.Users.GetByID(c.Req.Context(), id)
_, err := store.GetUserByID(c.Req.Context(), id)
if err != nil {
if !database.IsErrUserNotExist(err) {
log.Error("Failed to get user by ID: %v", err)
Expand All @@ -185,7 +211,7 @@ func authenticatedUser(store AuthStore, ctx *macaron.Context, sess session.Store
if conf.Auth.EnableReverseProxyAuthentication {
webAuthUser := ctx.Req.Header.Get(conf.Auth.ReverseProxyAuthenticationHeader)
if len(webAuthUser) > 0 {
user, err := database.Users.GetByUsername(ctx.Req.Context(), webAuthUser)
user, err := store.GetUserByUsername(ctx.Req.Context(), webAuthUser)
if err != nil {
if !database.IsErrUserNotExist(err) {
log.Error("Failed to get user by name: %v", err)
Expand All @@ -194,7 +220,7 @@ func authenticatedUser(store AuthStore, ctx *macaron.Context, sess session.Store

// Check if enabled auto-registration.
if conf.Auth.EnableReverseProxyAutoRegistration {
user, err = database.Users.Create(
user, err = store.CreateUser(
ctx.Req.Context(),
webAuthUser,
gouuid.NewV4().String()+"@localhost",
Expand All @@ -219,7 +245,7 @@ func authenticatedUser(store AuthStore, ctx *macaron.Context, sess session.Store
if len(auths) == 2 && auths[0] == "Basic" {
uname, passwd, _ := tool.BasicAuthDecode(auths[1])

u, err := database.Users.Authenticate(ctx.Req.Context(), uname, passwd, -1)
u, err := store.AuthenticateUser(ctx.Req.Context(), uname, passwd, -1)
if err != nil {
if !auth.IsErrBadCredentials(err) {
log.Error("Failed to authenticate user: %v", err)
Expand All @@ -233,7 +259,7 @@ func authenticatedUser(store AuthStore, ctx *macaron.Context, sess session.Store
return nil, false, false
}

u, err := database.Users.GetByID(ctx.Req.Context(), uid)
u, err := store.GetUserByID(ctx.Req.Context(), uid)
if err != nil {
log.Error("GetUserByID: %v", err)
return nil, false, false
Expand All @@ -254,7 +280,7 @@ func AuthenticateByToken(store AuthStore, ctx context.Context, token string) (*d
log.Error("Failed to touch access token [id: %d]: %v", t.ID, err)
}

user, err := database.Users.GetByID(ctx, t.UserID)
user, err := store.GetUserByID(ctx, t.UserID)
if err != nil {
return nil, errors.Wrapf(err, "get user by ID [user_id: %d]", t.UserID)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/context/go_get.go
Expand Up @@ -27,7 +27,7 @@ func ServeGoGet() macaron.Handler {
repoName := c.Params(":reponame")
branchName := "master"

owner, err := database.Users.GetByUsername(c.Req.Context(), ownerName)
owner, err := database.Handle.Users().GetByUsername(c.Req.Context(), ownerName)
if err == nil {
repo, err := database.Handle.Repositories().GetByName(c.Req.Context(), owner.ID, repoName)
if err == nil && repo.DefaultBranch != "" {
Expand Down
2 changes: 1 addition & 1 deletion internal/context/org.go
Expand Up @@ -47,7 +47,7 @@ func HandleOrgAssignment(c *Context, args ...bool) {
orgName := c.Params(":org")

var err error
c.Org.Organization, err = database.Users.GetByUsername(c.Req.Context(), orgName)
c.Org.Organization, err = database.Handle.Users().GetByUsername(c.Req.Context(), orgName)
if err != nil {
c.NotFoundOrError(err, "get organization by name")
return
Expand Down
2 changes: 1 addition & 1 deletion internal/context/repo.go
Expand Up @@ -145,7 +145,7 @@ func RepoAssignment(pages ...bool) macaron.Handler {
if c.IsLogged && c.User.LowerName == strings.ToLower(ownerName) {
owner = c.User
} else {
owner, err = database.Users.GetByUsername(c.Req.Context(), ownerName)
owner, err = database.Handle.Users().GetByUsername(c.Req.Context(), ownerName)
if err != nil {
c.NotFoundOrError(err, "get user by name")
return
Expand Down
42 changes: 42 additions & 0 deletions internal/context/store.go
Expand Up @@ -16,6 +16,32 @@ type Store interface {
// TouchAccessTokenByID updates the updated time of the given access token to
// the current time.
TouchAccessTokenByID(ctx context.Context, id int64) error

// GetUserByID returns the user with given ID. It returns
// database.ErrUserNotExist when not found.
GetUserByID(ctx context.Context, id int64) (*database.User, error)
// GetUserByUsername returns the user with given username. It returns
// database.ErrUserNotExist when not found.
GetUserByUsername(ctx context.Context, username string) (*database.User, error)
// CreateUser creates a new user and persists to database. It returns
// database.ErrNameNotAllowed if the given name or pattern of the name is not
// allowed as a username, or database.ErrUserAlreadyExist when a user with same
// name already exists, or database.ErrEmailAlreadyUsed if the email has been
// verified by another user.
CreateUser(ctx context.Context, username, email string, opts database.CreateUserOptions) (*database.User, error)
// AuthenticateUser validates username and password via given login source ID.
// It returns database.ErrUserNotExist when the user was not found.
//
// When the "loginSourceID" is negative, it aborts the process and returns
// database.ErrUserNotExist if the user was not found in the database.
//
// When the "loginSourceID" is non-negative, it returns
// database.ErrLoginSourceMismatch if the user has different login source ID
// than the "loginSourceID".
//
// When the "loginSourceID" is positive, it tries to authenticate via given
// login source and creates a new user when not yet exists in the database.
AuthenticateUser(ctx context.Context, login, password string, loginSourceID int64) (*database.User, error)
}

type store struct{}
Expand All @@ -32,3 +58,19 @@ func (*store) GetAccessTokenBySHA1(ctx context.Context, sha1 string) (*database.
func (*store) TouchAccessTokenByID(ctx context.Context, id int64) error {
return database.Handle.AccessTokens().Touch(ctx, id)
}

func (*store) GetUserByID(ctx context.Context, id int64) (*database.User, error) {
return database.Handle.Users().GetByID(ctx, id)
}

func (*store) GetUserByUsername(ctx context.Context, username string) (*database.User, error) {
return database.Handle.Users().GetByUsername(ctx, username)
}

func (*store) CreateUser(ctx context.Context, username, email string, opts database.CreateUserOptions) (*database.User, error) {
return database.Handle.Users().Create(ctx, username, email, opts)
}

func (*store) AuthenticateUser(ctx context.Context, login, password string, loginSourceID int64) (*database.User, error) {
return database.Handle.Users().Authenticate(ctx, login, password, loginSourceID)
}
2 changes: 1 addition & 1 deletion internal/context/user.go
Expand Up @@ -19,7 +19,7 @@ type ParamsUser struct {
// and injects it as *ParamsUser.
func InjectParamsUser() macaron.Handler {
return func(c *Context) {
user, err := database.Users.GetByUsername(c.Req.Context(), c.Params(":username"))
user, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":username"))
if err != nil {
c.NotFoundOrError(err, "get user by name")
return
Expand Down
12 changes: 6 additions & 6 deletions internal/database/actions.go
Expand Up @@ -221,7 +221,7 @@ func (s *ActionsStore) MirrorSyncPush(ctx context.Context, opts MirrorSyncPushOp
}

apiCommits, err := opts.Commits.APIFormat(ctx,
NewUsersStore(s.db),
newUsersStore(s.db),
repoutil.RepositoryPath(opts.Owner.Name, opts.Repo.Name),
repoutil.HTMLURL(opts.Owner.Name, opts.Repo.Name),
)
Expand Down Expand Up @@ -470,7 +470,7 @@ func (s *ActionsStore) CommitRepo(ctx context.Context, opts CommitRepoOptions) e
return errors.Wrap(err, "touch repository")
}

pusher, err := NewUsersStore(s.db).GetByUsername(ctx, opts.PusherName)
pusher, err := newUsersStore(s.db).GetByUsername(ctx, opts.PusherName)
if err != nil {
return errors.Wrapf(err, "get pusher [name: %s]", opts.PusherName)
}
Expand Down Expand Up @@ -566,7 +566,7 @@ func (s *ActionsStore) CommitRepo(ctx context.Context, opts CommitRepoOptions) e
}

commits, err := opts.Commits.APIFormat(ctx,
NewUsersStore(s.db),
newUsersStore(s.db),
repoutil.RepositoryPath(opts.Owner.Name, opts.Repo.Name),
repoutil.HTMLURL(opts.Owner.Name, opts.Repo.Name),
)
Expand Down Expand Up @@ -617,7 +617,7 @@ func (s *ActionsStore) PushTag(ctx context.Context, opts PushTagOptions) error {
return errors.Wrap(err, "touch repository")
}

pusher, err := NewUsersStore(s.db).GetByUsername(ctx, opts.PusherName)
pusher, err := newUsersStore(s.db).GetByUsername(ctx, opts.PusherName)
if err != nil {
return errors.Wrapf(err, "get pusher [name: %s]", opts.PusherName)
}
Expand Down Expand Up @@ -852,7 +852,7 @@ func NewPushCommits() *PushCommits {
}
}

func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore UsersStore, repoPath, repoURL string) ([]*api.PayloadCommit, error) {
func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore *UsersStore, repoPath, repoURL string) ([]*api.PayloadCommit, error) {
// NOTE: We cache query results in case there are many commits in a single push.
usernameByEmail := make(map[string]string)
getUsernameByEmail := func(email string) (string, error) {
Expand Down Expand Up @@ -925,7 +925,7 @@ func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore UsersStore, re
func (pcs *PushCommits) AvatarLink(email string) string {
_, ok := pcs.avatars[email]
if !ok {
u, err := Users.GetByEmail(context.Background(), email)
u, err := Handle.Users().GetByEmail(context.Background(), email)
if err != nil {
pcs.avatars[email] = tool.AvatarLink(email)
if !IsErrUserNotExist(err) {
Expand Down
20 changes: 10 additions & 10 deletions internal/database/actions_test.go
Expand Up @@ -133,7 +133,7 @@ func TestActions(t *testing.T) {
}

func actionsCommitRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -436,7 +436,7 @@ func actionsListByUser(t *testing.T, ctx context.Context, s *ActionsStore) {
}

func actionsMergePullRequest(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -481,7 +481,7 @@ func actionsMergePullRequest(t *testing.T, ctx context.Context, s *ActionsStore)
}

func actionsMirrorSyncCreate(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -522,7 +522,7 @@ func actionsMirrorSyncCreate(t *testing.T, ctx context.Context, s *ActionsStore)
}

func actionsMirrorSyncDelete(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -563,7 +563,7 @@ func actionsMirrorSyncDelete(t *testing.T, ctx context.Context, s *ActionsStore)
}

func actionsMirrorSyncPush(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -628,7 +628,7 @@ func actionsMirrorSyncPush(t *testing.T, ctx context.Context, s *ActionsStore) {
}

func actionsNewRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -707,7 +707,7 @@ func actionsPushTag(t *testing.T, ctx context.Context, s *ActionsStore) {
// to the mock server because this function holds a lock.
conf.SetMockServer(t, conf.ServerOpts{})

alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -799,7 +799,7 @@ func actionsPushTag(t *testing.T, ctx context.Context, s *ActionsStore) {
}

func actionsRenameRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down Expand Up @@ -836,9 +836,9 @@ func actionsRenameRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
}

func actionsTransferRepo(t *testing.T, ctx context.Context, s *ActionsStore) {
alice, err := NewUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
alice, err := newUsersStore(s.db).Create(ctx, "alice", "alice@example.com", CreateUserOptions{})
require.NoError(t, err)
bob, err := NewUsersStore(s.db).Create(ctx, "bob", "bob@example.com", CreateUserOptions{})
bob, err := newUsersStore(s.db).Create(ctx, "bob", "bob@example.com", CreateUserOptions{})
require.NoError(t, err)
repo, err := newReposStore(s.db).Create(ctx,
alice.ID,
Expand Down
2 changes: 1 addition & 1 deletion internal/database/comment.go
Expand Up @@ -95,7 +95,7 @@ func (c *Comment) AfterSet(colName string, _ xorm.Cell) {

func (c *Comment) loadAttributes(e Engine) (err error) {
if c.Poster == nil {
c.Poster, err = Users.GetByID(context.TODO(), c.PosterID)
c.Poster, err = Handle.Users().GetByID(context.TODO(), c.PosterID)
if err != nil {
if IsErrUserNotExist(err) {
c.PosterID = -1
Expand Down
8 changes: 5 additions & 3 deletions internal/database/database.go
Expand Up @@ -122,9 +122,7 @@ func NewConnection(w logger.Writer) (*gorm.DB, error) {
return nil, errors.Wrap(err, "load login source files")
}

// Initialize stores, sorted in alphabetical order.
Users = NewUsersStore(db)

// Initialize the database handle.
Handle = &DB{db: db}
return db, nil
}
Expand Down Expand Up @@ -189,3 +187,7 @@ func (db *DB) Repositories() *RepositoriesStore {
func (db *DB) TwoFactors() *TwoFactorsStore {
return newTwoFactorsStore(db.db)
}

func (db *DB) Users() *UsersStore {
return newUsersStore(db.db)
}
4 changes: 2 additions & 2 deletions internal/database/issue.go
Expand Up @@ -408,7 +408,7 @@ func (issue *Issue) GetAssignee() (err error) {
return nil
}

issue.Assignee, err = Users.GetByID(context.TODO(), issue.AssigneeID)
issue.Assignee, err = Handle.Users().GetByID(context.TODO(), issue.AssigneeID)
if IsErrUserNotExist(err) {
return nil
}
Expand Down Expand Up @@ -614,7 +614,7 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
return fmt.Errorf("UpdateIssueUserByAssignee: %v", err)
}

issue.Assignee, err = Users.GetByID(context.TODO(), issue.AssigneeID)
issue.Assignee, err = Handle.Users().GetByID(context.TODO(), issue.AssigneeID)
if err != nil && !IsErrUserNotExist(err) {
log.Error("Failed to get user by ID: %v", err)
return nil
Expand Down

0 comments on commit d9ecdca

Please sign in to comment.