DEPO: логину bj — роль db_datawriter (как на тесте); при обновлении и в первичной установке

Процедуры Фонтвьель, вызванные bj (FTV_M2M_JOB → EVENTS → UPDATE_HANDBOOK,
CREATE, OPERATION), пишут в таблицы Fancy правами логина bj. На 9 у bj_user
был только db_datareader — «Запрещено разрешение INSERT на объект
OD_OBJECTS» (событие HANDBOOK, 22.10.2026); упали бы и поручения M2M. На
тесте — db_datareader + db_datawriter.

Роль выдаётся в наборе «Применить скрипты» (права администратора БД; новый
отпечаток — плашка на установках), в скачиваемом скрипте процедур, в
скрипте логина и при подготовке трансферных таблиц (первичная установка).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
fontvielle
2026-10-22 13:56:26 +03:00
parent 88985afe04
commit 7981105cec
4 changed files with 17 additions and 4 deletions
+8 -1
View File
@@ -101,6 +101,7 @@ func depoProcsHash(f FancyMSSQLSettings) string {
for _, fx := range depoSchemaFixes {
h.Write([]byte(fx.Name + "\n" + fx.SQL + "\n"))
}
h.Write([]byte("grant db_datawriter\n")) // 22.10.2026: роль записи логину bj — новый отпечаток, плашка на установках
for _, p := range depoProcInstallOrder {
h.Write([]byte(p.Name + "\n" + strings.TrimSpace(depoProcEffective(f, p.Name)) + "\n"))
}
@@ -147,6 +148,8 @@ func depoProcsScriptFor(f FancyMSSQLSettings, db, login string) string {
fmt.Fprintf(&b, "/* ===== %s ===== */\n%s\nGO\n\n", p.Name, strings.TrimRight(body, "\n"))
}
if depoLoginRe.MatchString(login) {
b.WriteString("/* Запись в таблицы Fancy: процедуры обработки M2M работают правами логина bj (без неё — «Запрещено разрешение INSERT на объект OD_OBJECTS») */\n")
fmt.Fprintf(&b, "IF IS_ROLEMEMBER(N'db_datawriter', N'%[1]s') = 0 ALTER ROLE db_datawriter ADD MEMBER %[2]s;\nGO\n", login, quoteIdent(login))
b.WriteString("/* Права логину bj на все процедуры: без прав OBJECT_ID не видит их и проверка пишет «нет процедур» */\n")
for _, p := range depoProcInstallOrder {
fmt.Fprintf(&b, "GRANT EXECUTE ON dbo.%s TO %s;\n", p.Name, quoteIdent(login))
@@ -181,6 +184,10 @@ func depoProcsInstallInto(ctx context.Context, adm, f FancyMSSQLSettings, dbName
}
}
if depoLoginRe.MatchString(grantLogin) {
// Запись в таблицы Fancy: процедуры Фонтвьель, вызванные bj, работают правами логина bj.
if _, err := db.ExecContext(ctx, "IF DATABASE_PRINCIPAL_ID(N'"+grantLogin+"') IS NOT NULL AND IS_ROLEMEMBER(N'db_datawriter', N'"+grantLogin+"') = 0 ALTER ROLE db_datawriter ADD MEMBER "+quoteIdent(grantLogin)); err != nil {
return fmt.Errorf("роль db_datawriter логину %s: %s", grantLogin, quikErrorDetail(err))
}
// Право на ВСЕ процедуры: без него OBJECT_ID под bj_user = NULL, и проверка пишет «нет процедур».
for _, p := range depoProcInstallOrder {
if _, err := db.ExecContext(ctx, "GRANT EXECUTE ON dbo."+p.Name+" TO "+quoteIdent(grantLogin)); err != nil {
@@ -294,7 +301,7 @@ func depoProcsInstall(ctx context.Context, f FancyMSSQLSettings, adminUser, admi
if err := depoProcsInstallInto(ctx, adm, f, f.DepoDB(), login); err != nil {
return "", err
}
msg := fmt.Sprintf("структура таблиц проверена; установлено процедур: %d (%s); право EXECUTE логину %s выдано", len(depoProcInstallOrder), depoProcOrderText(", "), login)
msg := fmt.Sprintf("структура таблиц проверена; установлено процедур: %d (%s); логину %s — EXECUTE и роль db_datawriter", len(depoProcInstallOrder), depoProcOrderText(", "), login)
log.Printf("depo-procs: %s", msg)
return msg, nil
}
+6 -2
View File
@@ -51,8 +51,9 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO "%[2]s";
fmt.Fprintf(&b, `-- Bridge&Join: логин для bj в базе DEPO. Microsoft SQL Server.
-- Выполнить в SSMS или sqlcmd под логином с правами sysadmin (или securityadmin + db_owner в базе %[1]s).
-- Пароль — из поля мастера; если там пусто, замените ЗАМЕНИТЕ_НА_ПАРОЛЬ на свой. Скрипт с паролем не храните.
-- Права: только чтение учётных таблиц DEPO (db_datareader). Запись — только в таблицы обмена FTV_M2M*,
-- её выдаёт скрипт таблиц на следующем шаге мастера. Скрипт можно запускать повторно.
-- Права: чтение учётных таблиц DEPO (db_datareader) и запись (db_datawriter) — процедуры обработки M2M
-- (FTV_M2M_JOB и др.), которые вызывает bj, создают документы, операции и юрлица Fancy правами этого логина.
-- Таблицы обмена FTV_M2M* выдаёт скрипт таблиц на следующем шаге мастера. Скрипт можно запускать повторно.
USE [master];
GO
@@ -75,6 +76,9 @@ GO
IF IS_ROLEMEMBER(N'db_datareader', N'%[2]s') = 0 ALTER ROLE db_datareader ADD MEMBER [%[2]s];
GO
IF IS_ROLEMEMBER(N'db_datawriter', N'%[2]s') = 0 ALTER ROLE db_datawriter ADD MEMBER [%[2]s];
GO
`, db, login, pw)
return b.String()
}
+2
View File
@@ -237,6 +237,8 @@ func depoTablesGrantSQL(pg bool, user string) []string {
fmt.Sprintf("IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = N'%[1]s' AND sid <> SUSER_SID(N'%[1]s')) ALTER USER [%[1]s] WITH LOGIN = [%[1]s]", user),
// чтение учётных таблиц DEPO (лица, счета, остатки, опции) — для сверки заявок
fmt.Sprintf("IF IS_ROLEMEMBER(N'db_datareader', N'%[1]s') = 0 ALTER ROLE db_datareader ADD MEMBER [%[1]s]", user),
// запись в таблицы Fancy — процедуры обработки M2M (FTV_M2M_JOB…) работают правами вызывающего (bj)
fmt.Sprintf("IF IS_ROLEMEMBER(N'db_datawriter', N'%[1]s') = 0 ALTER ROLE db_datawriter ADD MEMBER [%[1]s]", user),
}
for _, n := range depoTableNames() {
out = append(out, fmt.Sprintf("GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.%s TO [%s]", n, user))
+1 -1
View File
@@ -1,6 +1,6 @@
{{define "depoProcsBanner"}}{{if and (can "settings") depoProcsPending}}<div class="card" id="depo-procs-pending" style="border-color:var(--warn);background:var(--warn-weak)">
<h2 style="margin:0 0 6px">Обновление bj требует применить скрипты в базе DEPO</h2>
<p style="margin:0 0 8px">В этой версии bj обновлены процедуры обработки M2M в DEPO ({{depoProcOrder}}) и структура трансферных таблиц (FTV_M2M_EVENTS.GUID — NULL для событий справочника). Для их установки нужны <b>повышенные права на базу данных</b>: введите логин и пароль администратора SQL (sysadmin, обычно sa). Они используются один раз и не сохраняются.</p>
<p style="margin:0 0 8px">В этой версии bj обновлены процедуры обработки M2M в DEPO ({{depoProcOrder}}) и структура трансферных таблиц (FTV_M2M_EVENTS.GUID — NULL для событий справочника); логину bj — роль db_datawriter (процедуры обработки создают документы и юрлица Fancy его правами). Для их установки нужны <b>повышенные права на базу данных</b>: введите логин и пароль администратора SQL (sysadmin, обычно sa). Они используются один раз и не сохраняются.</p>
<form method="post" action="/admin/setup/fancy/depo-procs/install" style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end" onsubmit="return confirm('Применить обновлённые процедуры в базе DEPO? CREATE OR ALTER — данные не меняются.')">
<input type="hidden" name="section" value="sec-fancy-depo-procs">
<label style="display:flex;flex-direction:column;gap:3px">Логин администратора SQL<input type="text" name="admin_user" autocomplete="off" placeholder="sa" required></label>