Loop after error on ChangePrimaryKey
Opened this issue · 1 comments
Проблема состоит в том, что ошибка при смене ключа может приводить к зацикливанию входа на страницу. Мне не удалось получить такую ситуацию в результате правильных действий, но в результате некоторых манипуляций зацикливание я получал. Не могу 100% утверждать, что описанное ниже истина, но по крайней мере очень похоже на правду.
Причина складывается из двух вещей.
- После ошибки при смене ключа у нас остается новый ключ в таблице my_keys со статусом my_pending. По хорошему, его наверно нужно удалять в Rollback функции. Но так как решение второго пункта обходит эту ситуацию, поэтому останавливаться на этом моменте не будем.
- Рассмотрим таблицу my_keys после ошибки. Самый первый ключ имеет block_id = 0 и статус approved. Новый ключ после ошибочной транзакции имеет тоже block_id = 0 и статус my_pending. Теперь рассмотрим функции GetMyPublicKey и GetMyPrivateKey. Они имеют запросы вида
db.Single("SELECT private_key/public_key FROM " + myPrefix + "my_keys WHERE block_id = (SELECT max(block_id) FROM " + myPrefix + "my_keys).
SELECT max(block_id) FROM " + myPrefix + "my_keys возвратит у нас 0 и получается запрос
SELECT private_key/public_key FROM " + myPrefix + "my_keys WHERE block_id = 0.
То есть запрос получается неопределенный
На усмотрении движка БД может вернуться как approved запись, так и my_pending, которая имеет невалидный ключ. Чаще видимо возвращается первая запись,
При замене этого запроса на запрос
SELECT private_key/public_key FROM " + myPrefix + "my_keys WHERE status!='my_pending' order by block_id desc limit 0,1
Всякая двусмысленность исчезает и будет возвращаться последний одобренный ключ.
Зацикливание в нащем случае похоже как раз и просиходит при возврашении невалидного ключа в условии content.go
if (string(utils.BinToHex(userPublicKey)) != sessPublicKey && len(myPrivateKey) == 0) || (countUsers > 0 && len(myPrivateKey) > 0 && !bytes.Equal(myPublicKey, []byte(userPublicKey))) {
Похожи запросы с (SELECT max(block_id) FROM " + myPrefix + "my_keys встречаются еще в нескольких местах и по хорошему там тоже нужно исправить для избежания подобных ситуаций.
Я исправил ошибку с зацикливанием. Я меня на тестовом примере зацикливания в этом варианте нет. Там еще нужно было private_key удалять из my_keys, если при автоматическом логине была ошибка .
А по самой причине ошибки при смене ключа пока не стал менять.