Where are redmine groups' names are stored? - redmine

I know about groups_users table, but it contains key values only, and where are textual groups' names are stored?
Is it yaml-file or config file maybe?
Or some hardcoded values?

In Database, groups and users are the same (Stored in users table, with a type User or Group)
In Redmine architecture, there is a main object, Principal, which can either be a User or a Group.
Try Principal.where(type: "Group").

Related

setting foreign key and primary key in gcp firestore

I am new to GCP and NOSQL.
is it possible to have primary and foreign key in the GCP fire-store
Example: I have two table STUDENT and DEPARTMENT
table looks like below
Department-table
dept-id(primary key)
deptname
Student-table
dept-id(foreign key)
student-id
student name
can anybody please help in design this in GCP Fire-store?
To a database, a key is the same as any UUID/randomID and can be shared and used between users, teams, admins, businesses, of all kinds. what matters is how that data is associated. Since Firestore is a noSQL database, there is no direct relational references, so one key cannot be equal to another without including secondary lookups.
In the same way you would define a user profile by an ID, you can create an empty document with a random ID to facilitate the ID of a team, or in this case the department. You can also utilize string combinations if you have a team and a sub-team, so long as at the point of the database request you have access to the team/department ID, you can use Regex to match a string comparison.
Example: request.resource.data.name.matches('/^' + departmentID)
To make a foreign key work with Security Rules or within the client, you must get the key that contains the data as the key should be the name of the document in question to streamline the request as you cannot perform queries or loop through data within Security Rules.
I great read on this subject, I highly suggest this article
https://medium.com/firebase-developers/a-list-of-firebase-firestore-security-rules-for-your-project-fe46cfaf8b2a
But my suggestion is to use a key that represents the department directly rather than using additional resource to have a foreign key and managing it.
Firestore won't support referential integrity.
It means that you can use any (subject to rules and conventions) names for fields, but the semantic and additional functionality is to be maintained by you, rather than by the system.

DynamoDB table/index schema design for querying multi-valued attributes

I'm building a DynamoDB app that will eventually serve a large number (millions) of users. Currently the app's item schema is simple:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
email: "foo#foo.com",
... other attributes ...
}
When a new user signs up, or if a user wants to find another user by email address, we'll need to look up users by email instead of by userId. With the current schema that's easy: just use a global secondary index with email as the Partition Key.
But we want to enable multiple email addresses per user, and the DynamoDB Query operation doesn't support a List-typed KeyConditionExpression. So I'm weighing several options to avoid an expensive Scan operation every time a user signs up or wants to find another user by email address.
Below is what I'm planning to change to enable additional emails per user. Is this a good approach? Is there a better option?
Add a sort key column (e.g. itemTypeAndIndex) to allow multiple items per userId.
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
itemTypeAndIndex: "main", // sort key
email: "foo#foo.com",
... other attributes ...
}
If the user adds a second, third, etc. email, then add a new item for each email, like this:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
itemTypeAndIndex: "Email-2", // sort key
email: "bar#bar.com"
// no more attributes
}
The same global secondary index (with email as the Partition Key) can still be used to find both primary and non-primary email addresses.
If a user wants to change their primary email address, we'd swap the email values in the "primary" and "non-primary" items. (Now that DynamoDB supports transactions, doing this will be safer than before!)
If we need to delete a user, we'd have to delete all the items for that userId. If we need to merge two users then we'd have to merge all items for that userId.
The same approach (new items with same userId but different sort keys) could be used for other 1-user-has-many-values data that needs to be Query-able
Is this a good way to do it? Is there a better way?
Justin, for searching on attributes I would strongly advise not to use DynamoDB. I am not saying, you can't achieve this. However, I see a few problems that will eventually come in your path if you will go this root.
Using sort-key on email-id will result in creating duplicate records for the same user i.e. if a user has registered 5 email, that implies 5 records in your table with the same schema and attribute except email-id attribute.
What if a new use-case comes in the future, where now you also want to search for a user based on some other attribute(for example cell phone number, assuming a user may have more then one cell phone number)
DynamoDB has a hard limit of the number of secondary indexes you can create for a table i.e. 5.
Thus with increasing use-case on search criteria, this solution will easily become a bottle-neck for your system. As a result, your system may not scale well.
To best of my knowledge, I can suggest a few options that you may choose based on your requirement/budget to address this problem using a combination of databases.
Option 1. DynamoDB as a primary store and AWS Elasticsearch as secondary storage [Preferred]
Store the user records in DynamoDB table(let's call it UserTable)as and when a user registers.
Enable DynamoDB table streams on UserTable table.
Build an AWS Lambda function that reads from the table's stream and persists the records in AWS Elasticsearch.
Now in your application, use DynamoDB for fetching user records from id. For all other search criteria(like searching on emailId, phone number, zip code, location etc) fetch the records from AWS Elasticsearch. AWS Elasticsearch by default indexes all the attributes of your record, so you can search on any field within millisecond of latency.
Option 2. Use AWS Aurora [Less preferred solution]
If your application has a relational use-case where data are related, you may consider this option. Just to call out, Aurora is a SQL database.
Since this is a relational storage, you can opt for organizing the records in multiple tables and join them based on the primary key of those tables.
I will suggest for 1st option as:
DynamoDB will provide you durable, highly available, low latency primary storage for your application.
AWS Elasticsearch will act as secondary storage, which is also durable, scalable and low latency storage.
With AWS Elasticsearch, you can run any search query on your table. You can also do analytics on data. Kibana UI is provided out of the box, that you may use to plot the analytical data on a dashboard like (how user growth is trending, how many users belong to a specific location, user distribution based on city/state/country etc)
With DynamoDB streams and AWS Lambda, you will be syncing these two databases in near real-time [within few milliseconds]
Your application will be scalable and the search feature can further be enhanced to do filtering on multi-level attributes. [One such example: search all users who belong to a given city]
Having said that, now I will leave this up to you to decide. 😊

How to apply dynamic Row level Security based on Username and location?

This is related to Row-level security in Power BI. Here is a dummy table on which I want to implement this RLS.
The RLS formula I am using right now is -
[location] = LOOKUPVALUE([location],[login],USERPRINCIPALNAME())
My end requirement is to make this RLS work on the case where if a user logs in he should see the data if the location he is in and also should see other users who are in the same location.
But lookup is throwing an error:
A table of multiple values was supplied where a single value was expected
Also, a single user can have access to multiple location and a single location could have multiple users.
How I can achieve this level of Row-level security using either Lookup or using any other possible way?
Your requirement can also be done through this way, you need to work on both the Power BI desktop and app server to get this right.
In Desktop
Power BI Desktop allows you to create Roles.Click on Manage Roles
and then click on Create New Role.
You would need to create Roles based on the Location here.
For Example Create a rule Called as Location A and click on the
table and give the formula to filters on that table. For example,
[Location] = "A".
So, you can create 'n' number of roles like this and then publish the dashboard.
App.PowerBI.Com
Now, Open app.powerbi.com and then go to the corresponding dataset and
right click on it, select security - you will find the groups there.
On the Groups, enter the emailid's that should have access to it.
You can add a person in multiple groups, that will allow them to see
more than one group.
Testing
Desktop allows you to test it as well - you can click on view as
roles, to see what the user in that group sees.
Also to remember, only people who have access to the dashboard will be able to see the data inside it. So, you will need to share it with them and as well as need to add them inside the groups. If you fail to do one of it, then they won't see anything on the dashboard.
Most efficient Method
This is a better method and I think this is the one you are asking for,
[login] = username()
The function username() automatically gets the email address of the user that is logged in.
Create the above mentioned filter on the new role in the required table.
This way, you would still be adding those 50000 users manually inside the roles under the security section of the corresponding dataset.
But If they all belong to a particular group in an organization, and your Office-365 team has configured your back-end in the right way, then you will only need to enter the group.
But most companies don't have this configuration on their back-end as it is very difficult to control the data security.
Change the Data Model
To do your requirement, you also need to change your data model.
You will need to have two tables initially.
The Value Table - You can have many columns like name and all in there, but it doesn't matter.
The Email Address Table For Location as your second table.
Now Merge the Locations from Value Table to Email Address Table and that will be your final Table. Use this for visualizations but please be very clear on DAX - as you may have duplicate rows and different values.
Now Create RLS on this Table. It should work.
As the name goes, Row Level Security is applied on each rows. So, the formula will be evaluated for each row individually. So, your only option is to have a flat table with all the values.
I answered a question very similar to this one on another page. I will copy it here because I added a bit for the lookup function.
Embedded Power BI: Add Multiple Users in Row Level Security and assign different roles
If you have more than one data to filter against in a role, pass the list as a string path to RLS, parse it into a table, then return the row when it matches with a value in the column.
We do this if we are not actually passing username, but for cases like multiple sales offices, or making a view that compares data from multiple user accounts, or when a user belongs to different hierarchies in an organization, or basically any time you want to use multiple filters..
example input using sales ids
//Username() = "020104010|020104061|020104303|020104304"
//DAX
var userIds = Username()
VAR tbl=
GENERATE (
GENERATESERIES(1,PATHLENGTH(UserIds),1),
ROW ( "Key", PATHITEM ( userIds, [value]))
)
VAR valueList =
SELECTCOLUMNS ( tbl, "Key", [Key] )
return [sales_id_column] in valueList
If you need to add lookup functions, you can apply it when the ROW() statement is called.. it will look like this:
VAR tbl=
GENERATE (
GENERATESERIES(1,PATHLENGTH(UserIds),1),
VAR CurrentKey = [Value]
RETURN
ROW ( "Key", LOOKUPVALUE(Table[c1],Table[c2], PATHITEM ( userIds, CurrentKey )))
)
There is also a case when the table has a many to many relationship and cannot use multiple roles as identity. Or for this case specifically when you only want to use one role to filter many tables. In that case the username looks like this:
Username() = "Username:Bob|Location:A|Location:C"
The code will have an extra step to parse the inner path after you change the ":" to a "|". Then use a if conditional to check if the current table filters for this role. This approach supports a claims-based authorization where only one role needs to be created in RLS and everything can be done client-application side.
runtime is O(k(n log m)) where m is the number of claims you have applying RLS in the current table, n is the number of rows in the table, and k is the number of tables you are applying RLS on

Best way of giving user's the ability to create their own datastores?

I want the user's of my site to be able to upload information into a database. I know that Django doesn't really allow me to let the user's have their own dynamically created tables. So I'm wondering what is the most efficient way of handling this.
For instance if all user's want to save mailing lists containing names, emails, numbers etc Would I just put all of these into one giant table with a column for the user ID or is there a smarter way to do this?
The basic functionality would allow users to upload data from a CSV in a restricted format. i.e. email, name which would be placed into a table like this:
user | email | name
However, I'd like to further improve on this so that a user can specify their own fields. i.e. Add phone numbers, address or whatever other info they want. Perhaps also having the ability to add their own field headings under a model similar to the following.
user | field1 | field2 | field3 | field4
You don't need to create a new table for each user. You would do exactly what you said, have a single mailing list table and store each record with an associated user ID. Then, when a user wants to view their lists, you filter that table by user ID. Similarly, if a user wanted to modify a mailing list, you'd make sure that user has the same ID as the record they're trying to modify.
Django already has a very powerful user authentication and permissions system. You should use it to ensure that only logged in users can access their records.
I suggest you take some time and carefully ready the Django documentation and follow the First Steps tutorials. They'll give you a better understanding about how to set up your models and implement authentication.

Where does Sitecore stores the security restrictions for an item for each user roles?

I need to know if a user with a specific role has access to a specific item by just using the Sitecore database tables without using Sitecore API. So my question is in which table and in which column is it stored?
Security is stored against individual items in __Security field. This is a shared field and as such will be in SharedFields table. Security information is actually a pipe delimited list. NOTE: Going directly to the schema is not recommended as it may change at Sitecore's discretion.
SQL below will get the security for all items in the database, update the where clause as required to get security for the items you are interested.
SELECT Id, ItemId, FieldId, Value, Created, Updated
FROM SharedFields
WHERE FieldId = '{DEC8D2D5-E3CF-48B6-A653-8E69E2716641}' /* Guid is the ID of the __Security field */
Result:
8AA88E96-2110-4BE1-A554-BAE9C60536FF 418B3B60-61E2-4E6C-B98F-061C88239087 DEC8D2D5-E3CF-48B6-A653-8E69E2716641 au|sitecore\agency|pd|-item:write|-item:admin|!*|+item:read|-item:delete|-item:create|-item:rename|pe|-item:write|-item:admin|!*|+item:read|-item:delete|-item:create|-item:rename| 2011-03-07 11:48:14.563 2011-03-07 11:48:14.563
06A6DB6C-6DEF-40E0-8CF8-8E179888DBB8 F1AF5582-B6A2-4435-8307-2837C1644EFB DEC8D2D5-E3CF-48B6-A653-8E69E2716641 au|sitecore\agency|pd|-item:write|-item:admin|!*|+item:read|-item:delete|-item:create|-item:rename|pe|-item:write|-item:admin|!*|+item:read|-item:delete|-item:create|-item:rename| 2011-03-07 11:48:14.270 2011-03-07 11:48:14.270
The SQL schema is not setup like you may think. The rights are stored on a Sitecore item field and not a specific column in the table. In SQL it will just be part of the XML data for the content item. You could parse that but I don't recommend going directly to SQL. Can you explain why you must do this using SQL?
Security is associated with each individual item and with is in _Security field.
This field is shared and is in SharedFields Tables.
Each value is separated by pipe.
The information related to user roles are being stored in Users table with Role id and Role Name.