Neo4J: how to find out the mode of procedure - stored-procedures

Cypher query CALL dbms.procedures; allows to get name, signature, and description of all available stored procedures at Neo4J server.
Is there a Cypher query to find out the mode of procedure(s)?
Source code of procedure should contain the annotation #Procedure with element mode. Value of the attribute mode indicates the type of actions (READ (default mode), WRITE, SCHEMA, DBMS) that can perform this procedure.

Adding 'mode' here is a good idea, I'll add it to the issues list.
In the meantime, dmbs.procedures() does YIELD roles (in the enterprise edition), which you can use to reason to the associated mode, at least where the basic roles are used.
I think this logic should be sound:
call dbms.procedures() yield name, roles
with name, roles,
case when 'reader' in roles then 'READ'
when 'publisher' in roles then 'WRITE'
when 'architect' in roles then 'SCHEMA'
when 'admin' in roles then 'DBMS'
end as mode
return name, roles, mode
order by mode asc
I'll look for solutions for the community edition.

Related

Can the flipper gem return a count of enabled users?

We are exploring using the flipper gem (https://github.com/jnunemaker/flipper) to gate who sees new features. In one of our first tests, we want to show a specific feature to only the first X users that see a banner promoting it.
We looked at using a percentage, but the business is very specific on the number, and also wants to reach that number right away, then disable the feature for all other users, without disabling it for those that saw it first. Using a percentage, we weren't able to see a way to ensure the correct number would see it, and that everyone of the first x would see it.
Inside the gates/actor.rb, there is this:
enabled_actor_ids = value
which implies we could get the list of enabled ids, and perform a count on that, but we couldn't find whether or where that list may be exposed.
Since we are using the AR adapter as a trial, we instead created a scope on an actor object that joins to the flipper_gates table, but this feels extremely fragile and getting very much into the inner workings of the gem.
Any advice is greatly appreciated.
Nowadays you can do Flipper[:some_feature].actors_value.size, assuming you've configured your default flipper instance with Flipper.configure.
https://github.com/jnunemaker/flipper/blob/196946c63aee1eaa09fa25e945cdbff896fe71e5/lib/flipper/feature.rb#L258-L260
You should be able to accomplish this by programmatically turning the feature on for Individual Actors until an upper limit is reached.
IMPORTANT NOTE: according to the documentation:
The individual actor gate is typically not designed for hundreds or
thousands of actors to be enabled. This is an explicit choice to make
it easier to batch load data from the adapters instead of performing
individual checks for actors over and over. If you need to enable
something for more than 20 individual people, I would recommend using
a group.
Now that we've agreed that we want to move forward with this anyways.. Let's talk about implementation.
Enabling the feature for an actor
The first thing you need to do is to ensure that the actor (probably a User) responds to flipper_id and that the flipper_id is unique for every actor. Once that is set up, you should be able to simply do enable the feature for a user when they see the banner like this:
flipper[:stats].enable_actor user
Counting actors enrolled in a feature
Now, in order to determine if we should enable the feature for a user, we need to determine how many users have been enrolled in the feature.
To do this we can query the Gate directly:
Flipper::Adapters::ActiveRecord::Gate.where(
feature_key: "stats",
key: "actors"
).count
This will return a count of the number of actors enrolled in a feature.
How do we know that works?
Well, let's take a look at the gem.
flipper[:stats].enable_actor actually calls Feature#enable_actor with the user we passed in earlier (that responds to flipper_id) being passed in as the actor.
Next, Feature#enable_actor passes the actor into Types::Actor.wrap which creates a new instance of Types::Actor which checks to make sure the actor isn't nil and that it has a flipper_id and then sets two instance variables, thing which is set to the actor, and value which is set to the flipper_id of the actor.
Now that we have an instance of Types::Actor, we pass it into Feature#enable which looks up the gate which in our case would be a Gates::Actor instance. Finally we call enable on the adaptor (which in your case is ActiveRecord).
In Adapters::ActiveRecord.enable we first look at gate.data_type which in our case, is :set. From there we do:
#gate_class.create! do |g|
g.feature_key = feature.key
g.key = gate.key
g.value = thing.value.to_s
end
Where, as mentioned earlier, thing.value is the flipper_id. Bingo! #gate_class is the active record class responsible for the gates table and the default table name is "flipper_gates".
Now we know exactly what to query to get a count of the actors enrolled in the feature!
number_of_actors_enrolled_in_stats_feature = Flipper::Adapters::ActiveRecord::Gate.where(
feature_key: "stats",
key: "actors"
).count

Is it possible to modify database using SQL injection with Active Record [duplicate]

This question already has answers here:
Rails methods vulnerable to SQL injection?
(2 answers)
Closed 7 years ago.
Using Rails 4.0 I have a controller action which uses request parameters in an active record query:
#clients = Client.where(params[:where]).order(params[:order]).limit(params[:limit])
Would it be possible for a user, using sql injection, to modify the database, or obtain information from the database that is not contained in the clients table?
If so an example would be greatly appreciated, as well as a simple method to prevent the possibility (I understand that placeholders or hash parameters would remove the vulnerablity but I don't see how to create the same functionality using them)
Thanks in advance.
Edit
I understand that these methods have vulnerabilities. My question concerns the extent of the vulnerablity. I was not able to find the answer to my specific question in the rails guides.
The where method assumes that its argument is a SQL fragment if it's a string.
What happens next probably depends on the database used, for example on mysql
Active Record turns off the ability for a query to contain multiple statements, so it's not just a case of injecting a where clause with a ';'.
Current versions of rails use prepared statements on postgres, which also forbids the injection of multiple statements.
In general relying on this seems extremely risky and may vary on other databases. Even if data modification / theft is not possible, denial of service would be trivial.
It would also be possible to steal information of the form "is there a user with email address xyz" by using a subquery that uses EXISTS. With a little time an patience you could also extract values, for example if I know a user's id and want to extract their email address I could run subselects of the form
SELECT * from users where id = 123 and email_address like 'A%'
If I get results then I know the email address starts with A, and I can move onto the next letter. If not then I check whether the email address starts with B and so on. Once I've got the first character, then queries of the form
SELECT * from users where id = 123 and email_address like 'FA%'
SELECT * from users where id = 123 and email_address like 'FB%'
SELECT * from users where id = 123 and email_address like 'FC%'
allow me to extract the second character of the email address. With a few thousand queries you could get their whole email address.
Another way to do this would be to use the sleep function on mysql - it would allow the extraction of variables one byte at a time based on how long the page took to load
You can found your response here: http://rails-sqli.org/
This website lists many query methods and options in ActiveRecord which do not sanitize raw SQL arguments and are not intended to be called with unsafe user input

LDAP "relational" group membership filter

I am trying to create a (single) LDAP filter that will find users with various attributes (status, create date, etc) who are also members of a particular group. Normally the answer would be to filter on the "memberOf" attribute -- but unfortunately users in our directory do not have this attribute -- instead of members referring to their groups, only groups refer to their members (using uniqueMember).
I read in Mr. Tendys' comment in another question that there is an overlay that will add memberOf to users in such cases. For whatever reason, this was not done in our case, and recreating the directory, as Mr. Tendys says is necessary to create the attribute for existing users, is a non-starter.
Currently we can search for the group separately from the other attributes like this:
Group:
BaseDN: ou=groups,dc=mycompany,dc=com
Query: (&(objectClass=groupofuniquenames)(description=My Funky Group))
(And then pull the uniqueMember attributes)
Other attributes:
BaseDN: dc=mycompany,dc=com
Query: (&(objectClass=person)(myCreateDate>=2010-10-27T10:49:42-04:00)(myUserType=E))
Relationally, my instinct is to join the uniqueMember attribute of the group to the DNs we get from the other attribute filter, but my investigation has not shown that this is possible in LDAP.
Admittedly, I am not an LDAP expert. I am much more experienced in the relational database would, but I have been nipping around the edges of LDAP for some time now. All of which is to say that I know some things, but there may be fundamentals I am missing.
How do I "join" these two filters, so I don't have to coalate the responses outside of my directory (a Java web service, for what its worth).
There are no joins in LDAP (unless there is something I haven't discovered yet!) You have to search the group members and check their attributes individually, or enumerate the users with matching attributes and check their group memberships, whichever makes more sense performance wise.

Identifying a connection ID in Postgres

I have a Postgres database (9) that I am writing a trigger for. I want the trigger to set the modification time, and user id for a record. In Firebird you have a CONNECTIONID that you can use in a trigger, so you could add a value to a table when you connect to the database (this is a desktop application, so connections are persistent for the lifetime of the app), something like this:
UserId | ConnectionId
---------------------
544 | 3775
and then look up in the trigger that connectionid 3775 belongs to userid 544 and use 544 as the user that modified the record.
Is there anything similar I can use in Postgres?
you could use the process id. It can be retrieved with:
pg_backend_pid()
With this pid you can also use the table pg_stat_activity to get more information about the current backend, althouht you already should know everything, since you are using this backend.
Or better. Just create a serial, and retrieve one value from it for each connection:
CREATE SEQUENCE 'connectionids';
And then:
SELECT next_val('connectionids');
in each connection, to retrieve a connection unique id.
One way is to use the custom_variable_classes configuration option. It appears to be designed to allow the configuration of add-on modules, but can also be used to store arbitrary values in the current database session.
Something along the lines of the following needs to be added to postgresql.conf:
custom_variable_classes = 'local'
When you first connect to the database you can store whatever information you require in the custom class, like so:
SET local.userid = 'foobar';
And later in on you can retrieve this value with the current_setting() function:
SELECT current_setting('local.userid');
Adding an entry to a log table might look something like this:
INSERT INTO audit_log VALUES (now(), current_setting('local.userid'), ...)
While it may work for your desktop use case, note that process ID numbers do rollover (32768 is a common upper limit), so using them as a unique key to identify a user can run into problems. If you ever end up with leftover data from a previous session in the table that's tracking user->process mapping, that can collide with newer connections assigned the same process id once it's rolled over. It may be sufficient for your app to just make sure you aggressively clean out old mapping entries, perhaps at startup time given how you've described its operation.
To avoid this problem in general, you need to make a connection key that includes an additional bit of information, such as when the session started:
SELECT procpid,backend_start FROM pg_stat_activity WHERE procpid=pg_backend_pid();
That has to iterate over all of the connections active at the time to compute, so it does add a bit of overhead. It's possible to execute that a bit more efficiently starting in PostgreSQL 8.4:
SELECT procpid,backend_start FROM pg_stat_get_activity(pg_backend_pid());
But that only really matters if you have a large number of connections active at once.
Use current_user if you need the database user (I'm not sure that's what you want by reading your question).

Best way to handle different types of Users?

I have a large Rails app that has 34 different types of Users through Single Table Inheritance. When the app was initially designed, it was assumed that the User would have different behaviors based on type. This assumption was wrong, so I'm looking to refactor.
The question is how would you refactor out the User STI?
Add a ton of boolean attributes to User (ie. User#is_employee?, User.is_contractor?)
Rename User#type to User#user_type and just do string matching based on the field
Some horrible lookup table solution
Something I'm missing...
Just to clarify, a User needs a 'type' for ACL reasons, but with STI they're really just empty models and STI causes issues with specing, general pain in the ass, etc.
It sounds like what you really need are roles rather than user types. I've found that this is usually the case when you end up with many user types, is because some users have more than one role.
A simple ACL model is: User has many roles, each role has many permissions.
The permission set for a user is the set of all permissions for all roles the user belongs to.
In more complicated cases a permission is often a calculated property rather than a row in a database, for the simple reason that permissions are some times target and time based (!).
#user.can_view_payroll_info_for?(#employee, 2.years.ago) ==> true
#user.can_view_payroll_info_for?(#employee, Time.now) ==> false
Most of the time though, a role is as high resolution as you need to get:
#john.has_role(:content_author) ==> true
#john.has_role(:moderator) ==> true
#benny.has_role(:content_author) ==> true
#benny.has_role(:moderator) ==> false
#michael.has_role(:moderator) ==> true
#michael.has_role(:content_author) ==> false
You can implement it as simply as a comma separated (validated) string 'roles' column for the user or a join table if you want roles to be normalized.
Are all 34 models empty?
If they are you could do:
self.inheritance_column = nil
At the top of your User model, that way you can just check type:
if #user.type == "Employee"
# do something
end
It's tough to answer the question without knowing in what way your 'ACL reasons' will be using the type, but...
In my experience I have always gone with User#user_type. It always turned out for me that the cases were rare enough that this was good. Though I have only ever had a few user types. Another option (which could be what you were alluding to with your second option) would be to use method_missing to handle the string matching, and allow it to behave like option 1.
For example:
def method_missing(method, *args, &block)
if(method.to_s.starts_with?('is_'))
self.user_type == method.to_s.gsub("is_", "").gsub("?", "")
end
end
this would return true for is_contractor? if the user_type is contractor.
Note that the snippet provided is untested, and that the chained gsub's are pretty awful looking. I'm sure this can be written as a nice little regular expression or in some other clever way.

Resources