feat(api,install): исключения fail2ban и смена своего никнейма

- установщик: `[DEFAULT] ignoreip` в jail.local — локальные сети и WireGuard
  исключены всегда, свой адрес добавляется флагом `--ignore-ip <ip|cidr>`;
  админ, часто заходящий в панель, больше не банит сам себя;
- участник может менять свой никнейм на сервере без MANAGE_NICKNAMES и без
  проверки иерархии (тайм-аут на себя по-прежнему запрещён);
- тест на смену своего ника и запрет self-тайм-аута.
This commit is contained in:
2026-09-19 23:27:26 +03:00
parent ac2b2cb18a
commit 0a82dd3a02
4 changed files with 62 additions and 4 deletions
+37
View File
@@ -452,6 +452,43 @@ func TestInstanceAdminEndpointsAndLimits(t *testing.T) {
}
}
func TestMemberCanChangeOwnNickname(t *testing.T) {
srv, _ := newTestServer(t)
ownerCookie := registerAndLogin(t, srv, "nick_owner", "nick-owner@example.com")
memberCookie := registerAndLogin(t, srv, "nick_member", "nick-member@example.com")
created := doJSON(t, srv, http.MethodPost, "/api/v1/guilds", `{"name":"Ники"}`, ownerCookie)
guild := decodeResponse[struct {
Guild struct {
ID string `json:"id"`
} `json:"guild"`
}](t, created)
doJSON(t, srv, http.MethodPost, "/api/v1/guilds/"+guild.Guild.ID+"/join", "", memberCookie)
member, err := srv.auth.UserByEmail(t.Context(), "nick-member@example.com")
if err != nil {
t.Fatalf("UserByEmail: %v", err)
}
self := doJSON(t, srv, http.MethodPatch,
"/api/v1/guilds/"+guild.Guild.ID+"/members/"+formatSnowflake(member.ID),
`{"nickname":"себе ник"}`, memberCookie)
if self.Code != http.StatusOK {
t.Fatalf("self nickname = %d, body = %s", self.Code, self.Body.String())
}
// Тайм-аут на себя запрещён даже владельцу.
owner, err := srv.auth.UserByEmail(t.Context(), "nick-owner@example.com")
if err != nil {
t.Fatalf("UserByEmail: %v", err)
}
timeout := doJSON(t, srv, http.MethodPatch,
"/api/v1/guilds/"+guild.Guild.ID+"/members/"+formatSnowflake(owner.ID),
`{"timeout_until":"2030-01-01T00:00:00Z"}`, ownerCookie)
if timeout.Code != http.StatusForbidden {
t.Fatalf("self timeout = %d, want 403", timeout.Code)
}
}
func TestMemberTimeoutRequiresPermission(t *testing.T) {
srv, _ := newTestServer(t)
ownerCookie := registerAndLogin(t, srv, "timeout_owner", "timeout-owner@example.com")