rpc: sync help.saveAppLog compatibility stub

Sync telesrv 245ff52 (rpc: implement help.saveAppLog compatibility stub).
This commit is contained in:
A 2026-07-19 03:07:11 +08:00
parent ee8e3574f7
commit f2c2fd0236
3 changed files with 93 additions and 0 deletions

View file

@ -39,6 +39,7 @@ func rpcAllowedWithoutAuthorization(id uint32) bool {
tg.HelpGetConfigRequestTypeID,
tg.HelpGetNearestDCRequestTypeID,
tg.HelpGetInviteTextRequestTypeID,
tg.HelpSaveAppLogRequestTypeID,
tg.HelpGetAppConfigRequestTypeID,
tg.HelpGetCountriesListRequestTypeID,
tg.HelpGetTimezonesListRequestTypeID,

View file

@ -23,6 +23,9 @@ func (r *Router) registerHelp(d *tlprofile.Dispatcher) {
registerRPC[*tg.HelpGetInviteTextRequest](d, tlprofile.SemanticMethodHelpGetInviteText, func(ctx context.Context, layerRequest *tg.HelpGetInviteTextRequest) (any, error) {
return &tg.HelpInviteText{Message: "Join me on Telegram."}, nil
})
registerRPC[*tg.HelpSaveAppLogRequest](d, tlprofile.SemanticMethodHelpSaveAppLog, func(ctx context.Context, _ *tg.HelpSaveAppLogRequest) (any, error) {
return r.onHelpSaveAppLog(ctx)
})
registerRPC[*tg.HelpGetAppUpdateRequest](d, tlprofile.SemanticMethodHelpGetAppUpdate, func(ctx context.Context, layerRequest *tg.HelpGetAppUpdateRequest) (any, error) {
source := layerRequest.
Source
@ -113,6 +116,21 @@ func (r *Router) registerHelp(d *tlprofile.Dispatcher) {
})
}
// onHelpSaveAppLog 为官方客户端的 fire-and-forget 应用遥测提供有界兼容应答。
// telesrv 当前不运营遥测产品,因此不读取、记录或持久化事件内容;请求已在 exact
// Layer admission 处受 wire/vector/aggregate/depth 限制。该方法按 TL 访问约束允许
// 未授权连接调用,但已登录 bot 必须拒绝。
func (r *Router) onHelpSaveAppLog(ctx context.Context) (bool, error) {
userID, authorized, err := r.currentUserID(ctx)
if err != nil {
return false, internalErr()
}
if authorized && r.userIsBot(ctx, userID) {
return false, botMethodInvalidErr()
}
return true, nil
}
func (r *Router) onHelpGetConfig(ctx context.Context) (*tg.Config, error) {
config := tdesktop.BuildConfig(r.cfg.DC, r.cfg.IP, r.cfg.Port, r.clock.Now(), r.cfg.PublicBaseURL)
userID, authorized, err := r.currentUserID(ctx)

View file

@ -0,0 +1,74 @@
package rpc
import (
"context"
"fmt"
"testing"
"github.com/iamxvbaba/td/clock"
"github.com/iamxvbaba/td/tg"
"github.com/iamxvbaba/td/tgerr"
"github.com/iamxvbaba/td/tlprofile"
"go.uber.org/zap/zaptest"
appusers "telesrv/internal/app/users"
"telesrv/internal/domain"
"telesrv/internal/store/memory"
)
func TestHelpSaveAppLogCompatibilityAckAcrossExactProfiles(t *testing.T) {
r := New(Config{}, Deps{Auth: &captureAuthService{}}, zaptest.NewLogger(t), clock.System)
requests := map[string]*tg.HelpSaveAppLogRequest{
"empty": {},
"android_device_stat": {
Events: []tg.InputAppEvent{{
Time: 1_721_234_567.25,
Type: "android_sdcard_exists",
Peer: 1,
Data: &tg.JSONBool{Value: true},
}},
},
}
contexts := map[string]context.Context{
"unauthenticated": context.Background(),
"user": WithUserID(context.Background(), 42),
}
for profile := tlprofile.Profile225; profile <= tlprofile.Profile228; profile++ {
for contextName, ctx := range contexts {
for requestName, req := range requests {
name := fmt.Sprintf("layer_%d/%s/%s", profile, contextName, requestName)
t.Run(name, func(t *testing.T) {
for attempt := 1; attempt <= 2; attempt++ {
result, method := dispatchExactLayerRPCTest(t, r, ctx, profile, req)
if method != "help.saveAppLog" {
t.Fatalf("attempt %d method = %q, want help.saveAppLog", attempt, method)
}
if value, ok := dispatchCanonicalValue(result).(bool); !ok || !value {
t.Fatalf("attempt %d response = %#v (%T), want true", attempt, dispatchCanonicalValue(result), result)
}
}
})
}
}
}
}
func TestHelpSaveAppLogRejectsBot(t *testing.T) {
ctx := context.Background()
users := memory.NewUserStore()
bot, err := users.Create(ctx, domain.User{
Phone: "+10000000001",
FirstName: "TelemetryBot",
AccessHash: 101,
Bot: true,
})
if err != nil {
t.Fatal(err)
}
r := New(Config{}, Deps{Users: appusers.NewService(users)}, zaptest.NewLogger(t), clock.System)
if _, err := r.onHelpSaveAppLog(WithUserID(ctx, bot.ID)); !tgerr.Is(err, "BOT_METHOD_INVALID") {
t.Fatalf("bot saveAppLog err = %v, want BOT_METHOD_INVALID", err)
}
}