From de1f524e25d9d4df2cb8a98b899c04dd086ea03d Mon Sep 17 00:00:00 2001 From: Gary Kramlich Date: Wed, 5 Jan 2022 14:59:35 -0600 Subject: [PATCH] Load users from the database during startup --- bridge/bridge.go | 2 ++ bridge/commands.go | 2 +- bridge/user.go | 38 ++++++++++++++++++++++++++++++++++++-- database/user.go | 10 +++++----- database/userquery.go | 16 ++++++++++++++++ 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/bridge/bridge.go b/bridge/bridge.go index 56a4e08..c3d08a9 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -141,6 +141,8 @@ func (b *Bridge) Start() error { go b.updateBotProfile() + go b.startUsers() + // Finally tell the appservice we're ready b.as.Ready = true diff --git a/bridge/commands.go b/bridge/commands.go index 48a441b..c7da3a0 100644 --- a/bridge/commands.go +++ b/bridge/commands.go @@ -123,7 +123,7 @@ func (l *loginCmd) Run(g *globals) error { return err } - if err := g.user.login(user.Token); err != nil { + if err := g.user.Login(user.Token); err != nil { fmt.Println(g.context.Stdout, "failed to login", err) return err diff --git a/bridge/user.go b/bridge/user.go index a008121..e7456ef 100644 --- a/bridge/user.go +++ b/bridge/user.go @@ -74,6 +74,36 @@ func (b *Bridge) NewUser(dbUser *database.User) *User { return user } +func (b *Bridge) getAllUsers() []*User { + b.usersLock.Lock() + defer b.usersLock.Unlock() + + dbUsers := b.db.User.GetAll() + users := make([]*User, len(dbUsers)) + + for idx, dbUser := range dbUsers { + user, ok := b.usersByMXID[dbUser.MXID] + if !ok { + user = b.loadUser(dbUser, nil) + } + users[idx] = user + } + + return users +} + +func (b *Bridge) startUsers() { + b.log.Debugln("Starting users") + + for _, user := range b.getAllUsers() { + // if user.ID != "" { + // haveSessions = true + // } + + go user.Connect() + } +} + func (u *User) SetManagementRoom(roomID id.RoomID) { u.bridge.managementRoomsLock.Lock() defer u.bridge.managementRoomsLock.Unlock() @@ -137,12 +167,16 @@ func (u *User) uploadQRCode(code string) (id.ContentURI, error) { return resp.ContentURI, nil } -func (u *User) login(token string) error { - err := u.User.Login(token) +func (u *User) Login(token string) error { + err := u.User.NewSession(token) if err != nil { return err } + return u.Connect() +} + +func (u *User) Connect() error { u.User.Session.AddHandler(u.messageHandler) u.log.Warnln("logged in, opening websocket") diff --git a/database/user.go b/database/user.go index 63f045e..9a27566 100644 --- a/database/user.go +++ b/database/user.go @@ -21,10 +21,10 @@ type User struct { Session *discordgo.Session } -// Login is just used to create the session and update the database and should -// only be called by bridge.User.Login which will continue setting up event -// handlers. -func (u *User) Login(token string) error { +// NewSession is just used to create the session and update the database. It +// should only be called by bridge.User.Connect which will continue setting up +// event handlers and everything else. +func (u *User) NewSession(token string) error { session, err := discordgo.New(token) if err != nil { return err @@ -50,7 +50,7 @@ func (u *User) Scan(row Scannable) *User { } if token.Valid { - if err := u.Login(token.String); err != nil { + if err := u.NewSession(token.String); err != nil { u.log.Errorln("Failed to login: ", err) } } diff --git a/database/userquery.go b/database/userquery.go index 2189e45..ff86371 100644 --- a/database/userquery.go +++ b/database/userquery.go @@ -25,3 +25,19 @@ func (uq *UserQuery) GetByMXID(userID id.UserID) *User { return uq.New().Scan(row) } + +func (uq *UserQuery) GetAll() []*User { + rows, err := uq.db.Query("SELECT mxid, id, management_room, token FROM user") + if err != nil || rows == nil { + return nil + } + + defer rows.Close() + + users := []*User{} + for rows.Next() { + users = append(users, uq.New().Scan(rows)) + } + + return users +}