PostgreSQL row-level security with views (protecting/hiding columns) [duplicate] - postgresql

I need strict control of the reading and writing of my Postgres data. Updatable views have always provided very good, strict, control of the reading of my data and allows me to add valuable computed columns. With Postgres 9.5 row level security has introduced a new and powerful way to control my data. But I can't use both technologies views, and row level security together. Why?

Basically because it wasn't possible to retroactively change how views work. I'd like to be able to support SECURITY INVOKER (or equivalent) for views but as far as I know no such feature presently exists.
You can filter access to the view its self with row security normally.
The tables accessed by the view will also have their row security rules applied. However, they'll see the current_user as the view creator because views access tables (and other views) with the rights of the user who created/owns the view.
Maybe it'd be worth raising this on pgsql-hackers if you're willing to step in and help with development of the feature you need, or pgsql-general otherwise?
That said, while views access tables as the creating user and change current_user accordingly, they don't prevent you from using custom GUCs, the session_user, or other contextual information in row security policies. You can use row security with views, just not (usefully) to filter based on current_user.

You can do this from PostgreSQL v15 on, which introduced the security_invoker option on views. If you turn that on, permissions on the underlying tables are checked as the user who calls the view, and RLS policies for the invoking user are used.
You can change existing views with
ALTER VIEW view_name SET (security_invoker = on);

The row level security policy can still be applied in the WHERE clause of the view. For example:
WHERE my_security_policy_function(person_id)

Related

Typo3 best practices - general variables

What is the best way to allow backend users to edit variables?
For example, I have a TYPO3 that sends out various e-Mail notifications and I want the backend users to be able to globally change the recipients. I started with template constants, until I found out, that backend users cannot edit the "template" module.
So what would be the best way to achieve this? I'm using Typo3 8.7.7
I would create a configuration record which can be edited by the backend users.
one way would be to include one file from fileadmin/ into the constants definition of typoscript. This file editors could change. But that could be a security risk, as the editors could define any constants.
the next option would be to define additional fields to the pages record, where these values could be set by any editor. In typoscript you access the field (maybe with slide = -1, so the value needs to be set just once)
another option: add these fields to a (special?) CE (ContentElement).
last option: use std CEs (e.g.HTML-content) at special pages or columns and use the content field (bodytext). (HTML-content has the advantage that the bodytext field is stored unmodified.)
Cleanest and leanest option would be option two (additional fields to table 'pages'). Option three and four are possible with pure typoscript, but you need to use CONTENT or RECORD object. If you use fix uids: remember that your editors might delete the CE and add a new CE with the same content (but another uid)
Addition:
As #Thomas-Löffler in his answer said:
you also can add a new kind of record/table, where an editor can insert or change the global values. Handling is like pages or tt_content. you can differ if your records are global (pid = 0, or special storage page) or dependent on page tree (rootpath), so you can have differnt values for different page subtrees.
I like Thomas‘ answer for providing a dedicated place to store the configuration option instead of putting it e.g. to pages because your configuration option is not bound to a page context.
Nonetheless for me personally it feels a bit odd to create a dedicated table for it. A table that would never hold more than one record.
That leads me to the conclusion that a key-value storage would be the right thing to use. Fortunately, TYPO3 ships System Registry. The only downside is that there‘s no interface for it so you‘d have to come up with your own forms to fill it. That‘s much easier if you go with Thomas‘ solution…
A clean and easy way is setting up a backend module with a form to set the email addresses.
Then you can grant the access right to a specific group or user and they are ready to go.

Can we add a comment column next to the Change column in Audit View of EA?

Is there a provision to store user entered comment during modification to the “Model” which can be shown in the “Audit View” along with “Original” and “CHANGE” columns of EA.
Can we add a comment column next to the Change column in Audit View of EA, where user entered comment can be stored. Please suggest the EA API to do the same.
You can not easily do that. You might modify the underlying database and add columns to existing tables (or even add your private tables). But that would break XMI export as these columns would not be ex-/imported and you're on your own to maintain this. An alternative is to use tagged values in general cases. But here I doubt it's feasible. So probably your own table with foreign key referring the audit would be the choice. However, it merely sound like you're trying to re-build a check-in mechanism. FWIW: in practice I found this mechanism counter-productive as people tend to comment either nothing or trivialities. So that it hinders more than it helps.
You can not modify the standard dialogs (e.g. fo the shown audit view). That means you have to write an add-in to create your own dialog.
The table that contains the audit is t_snapshot.

Two types of user in database how might I redesign my database?

I have a database in production, with two types of users. Similar to Uber, we have a 'Rider' and a 'Driver' user.
In my database, I have Users, Rider and Driver tables. The User table contains shared data between the two user types, and the Driver and Rider tables contain the remaining data.
When the database was originally designed, it was not thought that a Driver might also want to be a Rider. This use case how now arisen and I am unsure how to handle the database tables.
Currently, the email_address field has a unique constraint. The user also has a user_type field, which is either Rider or Driver.
My current thoughts are to remove the unique constraint on email_address, and create a unique index on email_address and user_type, which allows users to use both sides of the application.
This does create the problem of needing to specify which type of user is being worked with, for example, when calling /login. I think I would now need to do something like /login?type=rider.
Are there any better approaches to this? We are in production, so I can't just scrap and recreate, but I am open to migrating data if there is a better solution.
My suggestion is a bit too big for comment, so hear me out.
Exact solution is difficult as I have not seen how you are using these tables in the application. So this solution is designed on some assumptions.
At login time, you need to determine if the user wants to logon as driver or rider. Typically, link for drivers should be different that link for users. Or there should be a flag.
For riders, you don't need additional validation. But not everyone should be allowed to log in as driver ( e.g. If a user by mistake tries to logon as driver, system should not allow that).
That means your initial user table and driver table does not need any modification. Now if you are not a driver, user role should default to rider.
If you are a rider logging in as rider, no change is needed.
I am assuming you have a role setting mechanism somewhere in your code base.
However, if you are a driver logging in as driver, your existing logic should continue with this additional flag, i.e. you should check if flag is present in code and only then allow checking for driver in your tables. If you are a driver coming in as rider, the flag has to go as no.
Now you have 2 options. First is to get the driver coming in as rider data from driver table only, and second is to make an entry in rider table and use that. Both approaches will work ( you will have to tweak your application logic based on the flag to get to the correct table). My suggestion will be to go to the rider table, that should reduce further complications in the system. So basically, one user, if he is a driver sometimes and rider sometimes, should have entries in both driver and rider table( assuming your constraint is only on user tables) and you should use the correct entry based on the role the person is logging in. Hopefully, once logged in using the correct table, the changes to the system would be a minimum.

Does CitusDB support `CREATE VIEW`?

Assume we have a distributed CitusDB table named customer_reviews, and we try to create a view on it:
CREATE VIEW book_reviews AS
(SELECT * FROM customer_reviews WHERE product_group = 'Book');
This appears to work. But if we run:
SELECT COUNT(1) FROM book_reviews;
CitusDB gives the following error:
ERROR: cannot plan queries that include both regular and partitioned relations
Two questions:
Is there a way to work around this by manually creating the view on all worker nodes?
Is there a way to make CREATE VIEW and DROP VIEW work correctly on the master node, for apps which create and destroy views automatically at runtime?
UPDATE: View support is added to Citus with this PR.
First of all, I created an issue to track this. Please feel free to add your comments and feedback on that issue.
Until we implement this feature, I see two workarounds;
Using a UDF or a PL/pgSQL function to wrap the view query instead of creating the view. I added specific examples to the GitHub issue
Create some UDFs and PL/pgSQL functions to propagate views down to the shards on worker nodes and manipulate metadata to simulate views on the master node. I also added a prototype approach to the GitHub issue
I think what is best for you depends on your CREATE VIEW queries and your application stack. Could you explain your use-case and how do you plan to use views a bit more?

TSQL Naming conventions ~ What's this naming convention called?

Given that I'm using TSQL, what's the name of this style of naming?
\\servername\instance.database.schema.table
and what other items can be inserted in place of .dbo. in the previous naming instance? how does one go about creating those alternatives? links to answers welcome
Also, how would one refer to a job on the server instead of a table or a sproc?
My intention is for when I write up my work for documentation (say when I'm closing out my FogBugz ticket or something) then I want to be able to at least sound like I know what I'm doing ;)
(updated per links and comments)
Three & four part name are the most common references I've come across, but as you can see - there's lots of shorthand alternatives.
The dbo is the schema. You can create new schemas and assign db objects to the schema.
That is the entire path. If you're hitting a table within your default schema (this is dbo by default) all you need is table. (SELECT * FROM Addresses)
If you're hitting a table on a schema other than the user's default (or you want to protect yourself from future changes) then you'll put Schema.Table. (SELECT * FROM Customers.Addresses)
If you're looking to hit a table on a different database within the same server, you will need to put DatabaseName.Schema.Table. (SELECT * FROM ProductionDB.Customers.Addresses)
Finally, if you're looking to a hit a table on a different server all-together, you need the full path. These machines must also have a server-link, AFAIK.