github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/store/sqlstore/user_access_token_store.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "database/sql" 8 "fmt" 9 10 "github.com/mattermost/gorp" 11 "github.com/pkg/errors" 12 13 "github.com/masterhung0112/hk_server/v5/model" 14 "github.com/masterhung0112/hk_server/v5/store" 15 ) 16 17 type SqlUserAccessTokenStore struct { 18 *SqlStore 19 } 20 21 func newSqlUserAccessTokenStore(sqlStore *SqlStore) store.UserAccessTokenStore { 22 s := &SqlUserAccessTokenStore{sqlStore} 23 24 for _, db := range sqlStore.GetAllConns() { 25 table := db.AddTableWithName(model.UserAccessToken{}, "UserAccessTokens").SetKeys(false, "Id") 26 table.ColMap("Id").SetMaxSize(26) 27 table.ColMap("Token").SetMaxSize(26).SetUnique(true) 28 table.ColMap("UserId").SetMaxSize(26) 29 table.ColMap("Description").SetMaxSize(512) 30 } 31 32 return s 33 } 34 35 func (s SqlUserAccessTokenStore) createIndexesIfNotExists() { 36 s.CreateIndexIfNotExists("idx_user_access_tokens_user_id", "UserAccessTokens", "UserId") 37 } 38 39 func (s SqlUserAccessTokenStore) Save(token *model.UserAccessToken) (*model.UserAccessToken, error) { 40 token.PreSave() 41 42 if err := token.IsValid(); err != nil { 43 return nil, err 44 } 45 46 if err := s.GetMaster().Insert(token); err != nil { 47 return nil, errors.Wrap(err, "failed to save UserAccessToken") 48 } 49 return token, nil 50 } 51 52 func (s SqlUserAccessTokenStore) Delete(tokenId string) error { 53 transaction, err := s.GetMaster().Begin() 54 if err != nil { 55 return errors.Wrap(err, "begin_transaction") 56 } 57 58 defer finalizeTransaction(transaction) 59 60 if err := s.deleteSessionsAndTokensById(transaction, tokenId); err == nil { 61 if err := transaction.Commit(); err != nil { 62 // don't need to rollback here since the transaction is already closed 63 return errors.Wrap(err, "commit_transaction") 64 } 65 } 66 67 return nil 68 69 } 70 71 func (s SqlUserAccessTokenStore) deleteSessionsAndTokensById(transaction *gorp.Transaction, tokenId string) error { 72 73 query := "" 74 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 75 query = "DELETE FROM Sessions s USING UserAccessTokens o WHERE o.Token = s.Token AND o.Id = :Id" 76 } else if s.DriverName() == model.DATABASE_DRIVER_MYSQL { 77 query = "DELETE s.* FROM Sessions s INNER JOIN UserAccessTokens o ON o.Token = s.Token WHERE o.Id = :Id" 78 } 79 80 if _, err := transaction.Exec(query, map[string]interface{}{"Id": tokenId}); err != nil { 81 return errors.Wrapf(err, "failed to delete Sessions with UserAccessToken id=%s", tokenId) 82 } 83 84 return s.deleteTokensById(transaction, tokenId) 85 } 86 87 func (s SqlUserAccessTokenStore) deleteTokensById(transaction *gorp.Transaction, tokenId string) error { 88 89 if _, err := transaction.Exec("DELETE FROM UserAccessTokens WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil { 90 return errors.Wrapf(err, "failed to delete UserAccessToken id=%s", tokenId) 91 } 92 93 return nil 94 } 95 96 func (s SqlUserAccessTokenStore) DeleteAllForUser(userId string) error { 97 transaction, err := s.GetMaster().Begin() 98 if err != nil { 99 return errors.Wrap(err, "begin_transaction") 100 } 101 defer finalizeTransaction(transaction) 102 if err := s.deleteSessionsandTokensByUser(transaction, userId); err != nil { 103 return err 104 } 105 106 if err := transaction.Commit(); err != nil { 107 // don't need to rollback here since the transaction is already closed 108 return errors.Wrap(err, "commit_transaction") 109 } 110 return nil 111 } 112 113 func (s SqlUserAccessTokenStore) deleteSessionsandTokensByUser(transaction *gorp.Transaction, userId string) error { 114 query := "" 115 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 116 query = "DELETE FROM Sessions s USING UserAccessTokens o WHERE o.Token = s.Token AND o.UserId = :UserId" 117 } else if s.DriverName() == model.DATABASE_DRIVER_MYSQL { 118 query = "DELETE s.* FROM Sessions s INNER JOIN UserAccessTokens o ON o.Token = s.Token WHERE o.UserId = :UserId" 119 } 120 121 if _, err := transaction.Exec(query, map[string]interface{}{"UserId": userId}); err != nil { 122 return errors.Wrapf(err, "failed to delete Sessions with UserAccessToken userId=%s", userId) 123 } 124 125 return s.deleteTokensByUser(transaction, userId) 126 } 127 128 func (s SqlUserAccessTokenStore) deleteTokensByUser(transaction *gorp.Transaction, userId string) error { 129 if _, err := transaction.Exec("DELETE FROM UserAccessTokens WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil { 130 return errors.Wrapf(err, "failed to delete UserAccessToken userId=%s", userId) 131 } 132 133 return nil 134 } 135 136 func (s SqlUserAccessTokenStore) Get(tokenId string) (*model.UserAccessToken, error) { 137 token := model.UserAccessToken{} 138 139 if err := s.GetReplica().SelectOne(&token, "SELECT * FROM UserAccessTokens WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil { 140 if err == sql.ErrNoRows { 141 return nil, store.NewErrNotFound("UserAccessToken", tokenId) 142 } 143 return nil, errors.Wrapf(err, "failed to get UserAccessToken with id=%s", tokenId) 144 } 145 146 return &token, nil 147 } 148 149 func (s SqlUserAccessTokenStore) GetAll(offset, limit int) ([]*model.UserAccessToken, error) { 150 tokens := []*model.UserAccessToken{} 151 152 if _, err := s.GetReplica().Select(&tokens, "SELECT * FROM UserAccessTokens LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { 153 return nil, errors.Wrap(err, "failed to find UserAccessTokens") 154 } 155 156 return tokens, nil 157 } 158 159 func (s SqlUserAccessTokenStore) GetByToken(tokenString string) (*model.UserAccessToken, error) { 160 token := model.UserAccessToken{} 161 162 if err := s.GetReplica().SelectOne(&token, "SELECT * FROM UserAccessTokens WHERE Token = :Token", map[string]interface{}{"Token": tokenString}); err != nil { 163 if err == sql.ErrNoRows { 164 return nil, store.NewErrNotFound("UserAccessToken", fmt.Sprintf("token=%s", tokenString)) 165 } 166 return nil, errors.Wrapf(err, "failed to get UserAccessToken with token=%s", tokenString) 167 } 168 169 return &token, nil 170 } 171 172 func (s SqlUserAccessTokenStore) GetByUser(userId string, offset, limit int) ([]*model.UserAccessToken, error) { 173 tokens := []*model.UserAccessToken{} 174 175 if _, err := s.GetReplica().Select(&tokens, "SELECT * FROM UserAccessTokens WHERE UserId = :UserId LIMIT :Limit OFFSET :Offset", map[string]interface{}{"UserId": userId, "Offset": offset, "Limit": limit}); err != nil { 176 return nil, errors.Wrapf(err, "failed to find UserAccessTokens with userId=%s", userId) 177 } 178 179 return tokens, nil 180 } 181 182 func (s SqlUserAccessTokenStore) Search(term string) ([]*model.UserAccessToken, error) { 183 term = sanitizeSearchTerm(term, "\\") 184 tokens := []*model.UserAccessToken{} 185 params := map[string]interface{}{"Term": term + "%"} 186 query := ` 187 SELECT 188 uat.* 189 FROM UserAccessTokens uat 190 INNER JOIN Users u 191 ON uat.UserId = u.Id 192 WHERE uat.Id LIKE :Term OR uat.UserId LIKE :Term OR u.Username LIKE :Term` 193 194 if _, err := s.GetReplica().Select(&tokens, query, params); err != nil { 195 return nil, errors.Wrapf(err, "failed to find UserAccessTokens by term with value '%s'", term) 196 } 197 198 return tokens, nil 199 } 200 201 func (s SqlUserAccessTokenStore) UpdateTokenEnable(tokenId string) error { 202 if _, err := s.GetMaster().Exec("UPDATE UserAccessTokens SET IsActive = TRUE WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil { 203 return errors.Wrapf(err, "failed to update UserAccessTokens with id=%s", tokenId) 204 } 205 return nil 206 } 207 208 func (s SqlUserAccessTokenStore) UpdateTokenDisable(tokenId string) error { 209 transaction, err := s.GetMaster().Begin() 210 if err != nil { 211 return errors.Wrap(err, "begin_transaction") 212 } 213 defer finalizeTransaction(transaction) 214 215 if err := s.deleteSessionsAndDisableToken(transaction, tokenId); err != nil { 216 return err 217 } 218 if err := transaction.Commit(); err != nil { 219 // don't need to rollback here since the transaction is already closed 220 return errors.Wrap(err, "commit_transaction") 221 } 222 return nil 223 } 224 225 func (s SqlUserAccessTokenStore) deleteSessionsAndDisableToken(transaction *gorp.Transaction, tokenId string) error { 226 query := "" 227 if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { 228 query = "DELETE FROM Sessions s USING UserAccessTokens o WHERE o.Token = s.Token AND o.Id = :Id" 229 } else if s.DriverName() == model.DATABASE_DRIVER_MYSQL { 230 query = "DELETE s.* FROM Sessions s INNER JOIN UserAccessTokens o ON o.Token = s.Token WHERE o.Id = :Id" 231 } 232 233 if _, err := transaction.Exec(query, map[string]interface{}{"Id": tokenId}); err != nil { 234 return errors.Wrapf(err, "failed to delete Sessions with UserAccessToken id=%s", tokenId) 235 } 236 237 return s.updateTokenDisable(transaction, tokenId) 238 } 239 240 func (s SqlUserAccessTokenStore) updateTokenDisable(transaction *gorp.Transaction, tokenId string) error { 241 if _, err := transaction.Exec("UPDATE UserAccessTokens SET IsActive = FALSE WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil { 242 return errors.Wrapf(err, "failed to update UserAccessToken with id=%s", tokenId) 243 } 244 245 return nil 246 }