github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/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/mattermost/mattermost-server/v5/model"
    14  	"github.com/mattermost/mattermost-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_token", "UserAccessTokens", "Token")
    37  	s.CreateIndexIfNotExists("idx_user_access_tokens_user_id", "UserAccessTokens", "UserId")
    38  }
    39  
    40  func (s SqlUserAccessTokenStore) Save(token *model.UserAccessToken) (*model.UserAccessToken, error) {
    41  	token.PreSave()
    42  
    43  	if err := token.IsValid(); err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	if err := s.GetMaster().Insert(token); err != nil {
    48  		return nil, errors.Wrap(err, "failed to save UserAccessToken")
    49  	}
    50  	return token, nil
    51  }
    52  
    53  func (s SqlUserAccessTokenStore) Delete(tokenId string) error {
    54  	transaction, err := s.GetMaster().Begin()
    55  	if err != nil {
    56  		return errors.Wrap(err, "begin_transaction")
    57  	}
    58  
    59  	defer finalizeTransaction(transaction)
    60  
    61  	if err := s.deleteSessionsAndTokensById(transaction, tokenId); err == nil {
    62  		if err := transaction.Commit(); err != nil {
    63  			// don't need to rollback here since the transaction is already closed
    64  			return errors.Wrap(err, "commit_transaction")
    65  		}
    66  	}
    67  
    68  	return nil
    69  
    70  }
    71  
    72  func (s SqlUserAccessTokenStore) deleteSessionsAndTokensById(transaction *gorp.Transaction, tokenId string) error {
    73  
    74  	query := ""
    75  	if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
    76  		query = "DELETE FROM Sessions s USING UserAccessTokens o WHERE o.Token = s.Token AND o.Id = :Id"
    77  	} else if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
    78  		query = "DELETE s.* FROM Sessions s INNER JOIN UserAccessTokens o ON o.Token = s.Token WHERE o.Id = :Id"
    79  	}
    80  
    81  	if _, err := transaction.Exec(query, map[string]interface{}{"Id": tokenId}); err != nil {
    82  		return errors.Wrapf(err, "failed to delete Sessions with UserAccessToken id=%s", tokenId)
    83  	}
    84  
    85  	return s.deleteTokensById(transaction, tokenId)
    86  }
    87  
    88  func (s SqlUserAccessTokenStore) deleteTokensById(transaction *gorp.Transaction, tokenId string) error {
    89  
    90  	if _, err := transaction.Exec("DELETE FROM UserAccessTokens WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil {
    91  		return errors.Wrapf(err, "failed to delete UserAccessToken id=%s", tokenId)
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func (s SqlUserAccessTokenStore) DeleteAllForUser(userId string) error {
    98  	transaction, err := s.GetMaster().Begin()
    99  	if err != nil {
   100  		return errors.Wrap(err, "begin_transaction")
   101  	}
   102  	defer finalizeTransaction(transaction)
   103  	if err := s.deleteSessionsandTokensByUser(transaction, userId); err != nil {
   104  		return err
   105  	}
   106  
   107  	if err := transaction.Commit(); err != nil {
   108  		// don't need to rollback here since the transaction is already closed
   109  		return errors.Wrap(err, "commit_transaction")
   110  	}
   111  	return nil
   112  }
   113  
   114  func (s SqlUserAccessTokenStore) deleteSessionsandTokensByUser(transaction *gorp.Transaction, userId string) error {
   115  	query := ""
   116  	if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
   117  		query = "DELETE FROM Sessions s USING UserAccessTokens o WHERE o.Token = s.Token AND o.UserId = :UserId"
   118  	} else if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
   119  		query = "DELETE s.* FROM Sessions s INNER JOIN UserAccessTokens o ON o.Token = s.Token WHERE o.UserId = :UserId"
   120  	}
   121  
   122  	if _, err := transaction.Exec(query, map[string]interface{}{"UserId": userId}); err != nil {
   123  		return errors.Wrapf(err, "failed to delete Sessions with UserAccessToken userId=%s", userId)
   124  	}
   125  
   126  	return s.deleteTokensByUser(transaction, userId)
   127  }
   128  
   129  func (s SqlUserAccessTokenStore) deleteTokensByUser(transaction *gorp.Transaction, userId string) error {
   130  	if _, err := transaction.Exec("DELETE FROM UserAccessTokens WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
   131  		return errors.Wrapf(err, "failed to delete UserAccessToken userId=%s", userId)
   132  	}
   133  
   134  	return nil
   135  }
   136  
   137  func (s SqlUserAccessTokenStore) Get(tokenId string) (*model.UserAccessToken, error) {
   138  	token := model.UserAccessToken{}
   139  
   140  	if err := s.GetReplica().SelectOne(&token, "SELECT * FROM UserAccessTokens WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil {
   141  		if err == sql.ErrNoRows {
   142  			return nil, store.NewErrNotFound("UserAccessToken", tokenId)
   143  		}
   144  		return nil, errors.Wrapf(err, "failed to get UserAccessToken with id=%s", tokenId)
   145  	}
   146  
   147  	return &token, nil
   148  }
   149  
   150  func (s SqlUserAccessTokenStore) GetAll(offset, limit int) ([]*model.UserAccessToken, error) {
   151  	tokens := []*model.UserAccessToken{}
   152  
   153  	if _, err := s.GetReplica().Select(&tokens, "SELECT * FROM UserAccessTokens LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
   154  		return nil, errors.Wrap(err, "failed to find UserAccessTokens")
   155  	}
   156  
   157  	return tokens, nil
   158  }
   159  
   160  func (s SqlUserAccessTokenStore) GetByToken(tokenString string) (*model.UserAccessToken, error) {
   161  	token := model.UserAccessToken{}
   162  
   163  	if err := s.GetReplica().SelectOne(&token, "SELECT * FROM UserAccessTokens WHERE Token = :Token", map[string]interface{}{"Token": tokenString}); err != nil {
   164  		if err == sql.ErrNoRows {
   165  			return nil, store.NewErrNotFound("UserAccessToken", fmt.Sprintf("token=%s", tokenString))
   166  		}
   167  		return nil, errors.Wrapf(err, "failed to get UserAccessToken with token=%s", tokenString)
   168  	}
   169  
   170  	return &token, nil
   171  }
   172  
   173  func (s SqlUserAccessTokenStore) GetByUser(userId string, offset, limit int) ([]*model.UserAccessToken, error) {
   174  	tokens := []*model.UserAccessToken{}
   175  
   176  	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 {
   177  		return nil, errors.Wrapf(err, "failed to find UserAccessTokens with userId=%s", userId)
   178  	}
   179  
   180  	return tokens, nil
   181  }
   182  
   183  func (s SqlUserAccessTokenStore) Search(term string) ([]*model.UserAccessToken, error) {
   184  	term = sanitizeSearchTerm(term, "\\")
   185  	tokens := []*model.UserAccessToken{}
   186  	params := map[string]interface{}{"Term": term + "%"}
   187  	query := `
   188  		SELECT
   189  			uat.*
   190  		FROM UserAccessTokens uat
   191  		INNER JOIN Users u
   192  			ON uat.UserId = u.Id
   193  		WHERE uat.Id LIKE :Term OR uat.UserId LIKE :Term OR u.Username LIKE :Term`
   194  
   195  	if _, err := s.GetReplica().Select(&tokens, query, params); err != nil {
   196  		return nil, errors.Wrapf(err, "failed to find UserAccessTokens by term with value '%s'", term)
   197  	}
   198  
   199  	return tokens, nil
   200  }
   201  
   202  func (s SqlUserAccessTokenStore) UpdateTokenEnable(tokenId string) error {
   203  	if _, err := s.GetMaster().Exec("UPDATE UserAccessTokens SET IsActive = TRUE WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil {
   204  		return errors.Wrapf(err, "failed to update UserAccessTokens with id=%s", tokenId)
   205  	}
   206  	return nil
   207  }
   208  
   209  func (s SqlUserAccessTokenStore) UpdateTokenDisable(tokenId string) error {
   210  	transaction, err := s.GetMaster().Begin()
   211  	if err != nil {
   212  		return errors.Wrap(err, "begin_transaction")
   213  	}
   214  	defer finalizeTransaction(transaction)
   215  
   216  	if err := s.deleteSessionsAndDisableToken(transaction, tokenId); err != nil {
   217  		return err
   218  	}
   219  	if err := transaction.Commit(); err != nil {
   220  		// don't need to rollback here since the transaction is already closed
   221  		return errors.Wrap(err, "commit_transaction")
   222  	}
   223  	return nil
   224  }
   225  
   226  func (s SqlUserAccessTokenStore) deleteSessionsAndDisableToken(transaction *gorp.Transaction, tokenId string) error {
   227  	query := ""
   228  	if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
   229  		query = "DELETE FROM Sessions s USING UserAccessTokens o WHERE o.Token = s.Token AND o.Id = :Id"
   230  	} else if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
   231  		query = "DELETE s.* FROM Sessions s INNER JOIN UserAccessTokens o ON o.Token = s.Token WHERE o.Id = :Id"
   232  	}
   233  
   234  	if _, err := transaction.Exec(query, map[string]interface{}{"Id": tokenId}); err != nil {
   235  		return errors.Wrapf(err, "failed to delete Sessions with UserAccessToken id=%s", tokenId)
   236  	}
   237  
   238  	return s.updateTokenDisable(transaction, tokenId)
   239  }
   240  
   241  func (s SqlUserAccessTokenStore) updateTokenDisable(transaction *gorp.Transaction, tokenId string) error {
   242  	if _, err := transaction.Exec("UPDATE UserAccessTokens SET IsActive = FALSE WHERE Id = :Id", map[string]interface{}{"Id": tokenId}); err != nil {
   243  		return errors.Wrapf(err, "failed to update UserAccessToken with id=%s", tokenId)
   244  	}
   245  
   246  	return nil
   247  }