Files
new-api/controller/telegram_test.go
T
Seefs b6b97a66e3 fix: purge authentication data on hard user deletion (#6168)
* fix: purge authentication data on hard user deletion

* fix: fail closed when 2FA status lookup fails

* fix: reject stale Telegram login callbacks

* fix(twofa): prevent concurrent backup code and lockout bypasses

* fix(auth): harden user deletion and Telegram verification
2026-07-14 14:25:54 +08:00

79 lines
2.2 KiB
Go

package controller
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/url"
"sort"
"strconv"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestVerifyTelegramAuthorization(t *testing.T) {
const token = "telegram-test-token"
now := time.Unix(1_700_000_000, 0)
tests := []struct {
name string
authDate time.Time
mutate func(url.Values)
wantID string
wantErr string
}{
{name: "valid", authDate: now, wantID: "123456"},
{name: "small future clock skew", authDate: now.Add(90 * time.Second), wantID: "123456"},
{name: "expired", authDate: now.Add(-telegramAuthorizationMaxAge - time.Second), wantErr: "expired"},
{name: "too far in future", authDate: now.Add(telegramAuthorizationFutureSkew + time.Second), wantErr: "expired"},
{name: "invalid signature", authDate: now, mutate: func(values url.Values) { values.Set("hash", "00") }, wantErr: "signature"},
{name: "duplicate parameter", authDate: now, mutate: func(values url.Values) { values["id"] = append(values["id"], "654321") }, wantErr: "duplicate"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
params := signedTelegramAuthorization(token, tt.authDate)
if tt.mutate != nil {
tt.mutate(params)
}
telegramID, err := verifyTelegramAuthorization(params, token, now)
if tt.wantErr != "" {
require.Error(t, err)
assert.ErrorContains(t, err, tt.wantErr)
assert.Empty(t, telegramID)
return
}
require.NoError(t, err)
assert.Equal(t, tt.wantID, telegramID)
})
}
}
func signedTelegramAuthorization(token string, authDate time.Time) url.Values {
params := url.Values{
"auth_date": {strconv.FormatInt(authDate.Unix(), 10)},
"first_name": {"Test"},
"id": {"123456"},
}
keys := make([]string, 0, len(params))
for key := range params {
keys = append(keys, key)
}
sort.Strings(keys)
dataCheck := make([]string, 0, len(keys))
for _, key := range keys {
dataCheck = append(dataCheck, key+"="+params.Get(key))
}
secret := sha256.Sum256([]byte(token))
mac := hmac.New(sha256.New, secret[:])
_, _ = mac.Write([]byte(strings.Join(dataCheck, "\n")))
params.Set("hash", hex.EncodeToString(mac.Sum(nil)))
return params
}