Subject | Row-level security? |
---|---|
Author | ettotev |
Post date | 2007-09-22T20:29:35Z |
What I am asking for here is not actually the full row-level security
mechanism. (btw, does anyone know if there are plans to introduce that
in FB?) What I imagine I need would be statements like:
GRANT SELECT ON TRAN TO PUBLIC;
GRANT ALL ON TRAN WHERE TRATYPE = 'N' TO PUBLIC;
GRANT ALL ON TRAN WHERE TRATYPE = 'X' TO TRIGGER XGHG_AUID0;
Now the actual problem I'm trying to solve:
TRAN is a table with generic transactions, where each transaction has
transaction type TRATYPE.
Users should be able to view all records (all transaction types), but
should only be able to directly insert/update/delete transactions of
type 'N'. Some 'special' transactions will be maintained in other
tables (like XCHG in the example above) and then triggers on those
tables will insert/update/delete respective records in TRAN. For one
record in XCHG there could be more than one 'generic' transactions in
TRAN.
A major design requirement is that the database should be able to
enforce all business rules by itself, so that a user cannot create
invalid data even when they connect via a generic administration
client like isql or flamerobin or ibexpert. This means that all
solutions on the "application" side are not acceptable.
I guess one way to go would be:
GRANT SELECT ON TRAN TO PUBLIC;
CREATE VIEW TRAN_N AS SELECT * FROM TRAN WHERE TRATYPE='N';
GRANT ALL ON TRAN_N TO PUBLIC;
CREATE VIEW TRAN_X AS SELECT * FROM TRAN WHERE TRATYPE='X';
GRANT ALL ON TRAN_X TO TRIGGER XGHG_AUID0;
The major drawback I see here is that the application should read and
display the generic transactions from the table, but use the view
TRAN_N when it needs to insert/update/delete simple transactions
(TRATYPE='N'). The main application is a Delphi one and I think that
could easily be done there using the different SQL properties for
select/insert/update/delete that most component suites have. Still
somehow I don't like this approach, maybe because it requires a
separate view for each transaction type.
The direction I'm currently thinking in is to create a BEFORE trigger
for TRAN, where all operations for TRATYPE<>'N' are rejected if they
are not coming from the respective trigger on the other table (in the
example above, trigger XCHG_AUID0 for TRATYPE='X'). Then the question
is - how can I know when a request is coming from that specific
trigger and when not?
Of course any other suggestions are welcome.
Thanks in advance
Emil
mechanism. (btw, does anyone know if there are plans to introduce that
in FB?) What I imagine I need would be statements like:
GRANT SELECT ON TRAN TO PUBLIC;
GRANT ALL ON TRAN WHERE TRATYPE = 'N' TO PUBLIC;
GRANT ALL ON TRAN WHERE TRATYPE = 'X' TO TRIGGER XGHG_AUID0;
Now the actual problem I'm trying to solve:
TRAN is a table with generic transactions, where each transaction has
transaction type TRATYPE.
Users should be able to view all records (all transaction types), but
should only be able to directly insert/update/delete transactions of
type 'N'. Some 'special' transactions will be maintained in other
tables (like XCHG in the example above) and then triggers on those
tables will insert/update/delete respective records in TRAN. For one
record in XCHG there could be more than one 'generic' transactions in
TRAN.
A major design requirement is that the database should be able to
enforce all business rules by itself, so that a user cannot create
invalid data even when they connect via a generic administration
client like isql or flamerobin or ibexpert. This means that all
solutions on the "application" side are not acceptable.
I guess one way to go would be:
GRANT SELECT ON TRAN TO PUBLIC;
CREATE VIEW TRAN_N AS SELECT * FROM TRAN WHERE TRATYPE='N';
GRANT ALL ON TRAN_N TO PUBLIC;
CREATE VIEW TRAN_X AS SELECT * FROM TRAN WHERE TRATYPE='X';
GRANT ALL ON TRAN_X TO TRIGGER XGHG_AUID0;
The major drawback I see here is that the application should read and
display the generic transactions from the table, but use the view
TRAN_N when it needs to insert/update/delete simple transactions
(TRATYPE='N'). The main application is a Delphi one and I think that
could easily be done there using the different SQL properties for
select/insert/update/delete that most component suites have. Still
somehow I don't like this approach, maybe because it requires a
separate view for each transaction type.
The direction I'm currently thinking in is to create a BEFORE trigger
for TRAN, where all operations for TRATYPE<>'N' are rejected if they
are not coming from the respective trigger on the other table (in the
example above, trigger XCHG_AUID0 for TRATYPE='X'). Then the question
is - how can I know when a request is coming from that specific
trigger and when not?
Of course any other suggestions are welcome.
Thanks in advance
Emil