Ошибка применения пользовательского фильтра

Добрый день!

TS 3.3.2.211, Оракл

Создал раздел Карты. Раздал права доступа необходимым группам. У группы все пользователи нет прав на этот раздел вообще. В разделе Контакты создал пользовательский фильтр ссылающийся на созданный раздел. Для пользователя, у которого есть права на раздел Карты фильтр работает идеально. Если у пользователя нет прав на этот раздел, то получаем ошибку ORA-00904: "tbl_Card"."ContactID": invalid identifier. При этом на сервер отправляется вот такой вот запрос:

SELECT
        "ID",
        "Name",
        "Communication1",
        "AccountName",
        "AccountID",
        "ContactTypeID",
        "ContactTypeName"
FROM (
SELECT
        "tbl_Contact"."ID" "ID",
        "tbl_Contact"."Name" "Name",
        "tbl_Contact"."Communication1" "Communication1",
        "tbl_Account"."Name" "AccountName",
        "tbl_Contact"."AccountID" "AccountID",
        "tbl_Contact"."ContactTypeID" "ContactTypeID",
        "tbl_ContactType"."Name" "ContactTypeName"
FROM
        "TS"."vw_Contact" "tbl_Contact"
LEFT OUTER JOIN
        "TS"."vw_Account" "tbl_Account" ON "tbl_Account"."ID" = "tbl_Contact"."AccountID"
LEFT OUTER JOIN
        "TS"."tbl_ContactType" "tbl_ContactType" ON "tbl_ContactType"."ID" =
"tbl_Contact"."ContactTypeID"
WHERE (("tbl_Contact"."IsNotActive" > :pIsActive) AND
        (EXISTS
        (SELECT
                NULL "ID"
        FROM
                "TS"."tbl_Empty" "tbl_Card"
        WHERE ("tbl_Contact"."ID" = "tbl_Card"."ContactID" AND
                1 = 0 AND
                1 = 0 AND
                1 = 0 AND
                1 = 0))))
ORDER BY
        2 ASC
)
 WHERE ROWNUM = 40

Что я прописал не так для пользовательского фильтра в запросе? Сервис запроса прилагаю.

Нравится

14 комментариев

Здравствуйте!

В tbl_Empty нет поля ContactID:

SELECT 
                NULL "ID"
        FROM 
                "TS"."tbl_Empty" "tbl_Card"
        WHERE ("tbl_Contact"."ID" = "tbl_Card"."ContactID"

Если у пользователя нет прав на таблицу, то при построении запроса она заменяется на tbl_Empty, поэтому возникает такая ошибка.

Из решений вижу отключение фильтра перед открытием датасета, если нет прав на эту таблицу.

Сергей, спасибо за помощь. Действительно, в таблице tbl_Empty нет поля ContactID. Но я эту таблицу не подставлял, соответственно это делает ядро, в том случае, когда у пользователя нет доступа к этой таблице. Поэтому мне кажется, что тут в ядре надо что-то менять. Например, одновременно с подстановкой tbl_Empty все поля таблицы, к которой нет доступа, заменять на поле ID. Ваше предложение об отключении фильтра если нет прав на таблицу идеальное, но опять же, это должно делать ядро.

С моей стороны может быть сделано простое решение: добавить в таблицу tbl_Empty поле ContactID. Но тогда такое поле необходимо добавлять фактически для каждого раздела.

Может кто-то еще сталкивался с подобной ситуацией? Как решали данную проблему?

Здравствуйте!

В данном случае следует раздать права таким образом:

Дать права на чтение на tbl_Card группе Все пользователи;

Установить для нее признак "Администрируется по записям" и убрать из прав по умолчанию на записи группу Все пользователи.

в случае необхожимости можно отдельно скрывать кнопку раздела в меню в зависимости от прав пользователя.

В Вашем случае есть вариант воспользоваться отдельной функциоей получения результата запроса в CustomSqlColumn:

http://www.community.terrasoft.ua/blogs/8267#comment-34549

Анна, спасибо, но как-то неправильно давать права на чтение всем пользователям. Они вообще не должны видеть этот раздел, не говоря о его содержимом. Как Вы говорите можно скрыть раздел в зависимости от прав пользователя? Может все-таки можно в ядре что-то подправить? Ведь попытка обработать такую ситуацию ядром системы есть...

Записей они видеть не будут, только сам раздел.

Для того, чтобы скрыть раздел в меню, нужно в scr_Main в функции InitializeWorkspacesInfo() добавить проверку на вхождение пользователя в определнную группу, например.

amiCard.IsVisible = Value; //результат проверки

Я всё же настаиваю что это ошибка и вопрос необходимо передать разработчикам для исправления. Например сделать как при отображении детали, на которую нет прав доступа на чтение:

SELECT
	"ID",
	"SalesPointID",
	"SalesPointName",
	"PurchaseDate",
	"PurchaseNumber",
	"ContactID",
	"ContactName",
	"CardID",
	"CardNumber",
	"PromoutionCheckID",
	"CheckNumber",
	"DiscountTypeID",
	"DiscountTypeName",
	"BasicAmountPaid",
	"BasicTotalDiscount",
	"BasicTotalBonus",
	"CashierID",
	"CashierName"
FROM (
SELECT 
	NULL "ID",
	NULL "SalesPointID",
	NULL "SalesPointName",
	NULL "PurchaseDate",
	NULL "PurchaseNumber",
	NULL "ContactID",
	NULL "ContactName",
	NULL "CardID",
	NULL "CardNumber",
	NULL "PromoutionCheckID",
	NULL "CheckNumber",
	NULL "DiscountTypeID",
	NULL "DiscountTypeName",
	NULL "BasicAmountPaid",
	NULL "BasicTotalDiscount",
	NULL "BasicTotalBonus",
	NULL "CashierID",
	NULL "CashierName"
FROM 
	"TS"."tbl_Empty" "tbl_PromoutionPurchase"
LEFT OUTER JOIN
	"TS"."tbl_SalesPoint" "tbl_SalesPoint" ON "tbl_SalesPoint"."ID" = NULL
LEFT OUTER JOIN
	"TS"."vw_Contact" "tbl_Contact" ON "tbl_Contact"."ID" = NULL
LEFT OUTER JOIN
	"TS"."tbl_DiscountType" "tbl_DiscountType" ON "tbl_DiscountType"."ID" = NULL
LEFT OUTER JOIN
	"TS"."vw_Contact" "Cashier" ON "Cashier"."ID" = NULL
WHERE (1 = 0)
)
 WHERE ROWNUM <= 40

Я общалась на эту тему с разработчиками, в данном случае поведение системы соответсвует спецификации. За Ваш программный код Вы отвечаете самостоятельно.

В данном случае могу предложить поделиться постановкой задачи, которая Вами решается, чтобы мы могли предложить оптимальный с точки зрения системы способ реализции.

Анна, задача простая: необходимо дать пользователю, у которого есть право на чтение раздела Карты, вывести контакты, у которых есть карта, удовлетворяющая определённым условиям (по номеру, по типу и т.п.). Для этого в сервисе sq_Contacts (прикреплен к первому сообщению) я создал фильтр типа Exist с названием CardsFilter. Пытался сделать его на подобие аналогичных фильтров. Может я что-то перемудрил?

Здравствуйте.

Из конфигурации к сожалению мы не сможем обработать ситуацию, когда пользователь фильтрует (пользовательский фильтр) данные раздела, по критериям из другого раздела, доступа к которому у него нет.

Поэтому все же оптимальным решением, с точки зрения логики системы, будет решение описанное Анной в сообщении №4.

Дмитрий, для меня так и останется загадкой почему конфигурация может определить что при применении пользовательского фильтра у пользователя нет доступа в другой раздел и подставить вместо tbl_Card tbl_Empty, а вместо tbl_Card.ContactID подставить NULL (как в посте №7) она не может.

Ну что ж, объясню пользователям что это нормальная ошибка: нечего фильтровать по разделам, на которые у них нет доступа.

Ozzy, дело в том что эти данные подставляет не конфигурация, а ядро.
А почему Вы не хотите скрыть иконку "Раздела" для тех кому он не должен быть виден, а доступ на чтение на раздел "Карты" выдать?

Дмитрий, может так и сделаю, но это заплатка как бы получается. Гораздо лучше если бы это в ядре учли. Ведь это многим, как мне кажется, упростило бы жизнь.

Ozzy, я сообщу в департамент разработки о проблеме. По результатам Вам отпишу в этом топике.

Показать все комментарии