I'm using Symfony2 with doctrine2 and I need to design table relation with yml file.
The tables are: users, account and roles where users can be members of many accounts and have there different role.
Without doctrine I would create tables and one joining table with user_id,account_id and role_id.
With doctrine I have now this and I'm looking for a hint how to add there one more relation to table roles.
User:
type: entity
manyToMany:
accounts:
targetEntity: Accounts
joinTable:
name: UserAccount
joinColumns:
user_id:
referencedColumnName: id
inverseJoinColumns:
account_id:
referencedColumnName: id
In such case the only way you can go is create another entity called, let say UserAccountRole and connect to it with OneToMany.
User -> (OneToMany) -> UserAccountRole -> (ManyToOne) -> User
Account -> (OneToMany) -> UserAccountRole -> (ManyToOne) -> Account
Role -> (OneToMany) -> UserAccountRole -> (ManyToOne) -> Role
Related
I have a multi tenant application in AWS Amplify, I'm using the Custom-attribute-based multi-tenancy described here
All models have a composite key with "company" being the unique tenant ID, and the cognito user pool has a custom attribute custom:company which links the user to the tenant data.
Example type below:
type Customer #model
#key(fields: ["company", "id"])
#auth(rules: [
{ allow: owner, ownerField: "company", identityClaim: "custom:company"},
{ allow: groups, groups: ["Member"], operations: [read] },
{ allow: groups, groups: ["Admin"]},
])
{
company: ID!
id: ID!
...
}
I want to add user groups to cognito to manage the operations that different users can perform - e.g. Admin users can perform all operations, but Member users can only perform read
The problem is the first owner auth rule will match for anyone with the matching custom:company attribute, regardless of their Group.
Is there a way to combine owner and group #auth rules - i.e. both owner and groups needs to pass to have access to an item?
For example - users of the Member group is allowed but only when their custom:company attribute matches the company of the model
Another example - anyone with a matching custom:company attribute have access to an item but Members can only read
I am planning to use AWS Amplify as a backend for a mobile application. The App consists of two User Types (UserTypeA,UserTypeB). They have some common data points and some unique one's too.
UserTypeA(id, email, firstName, lastName, profilePicture, someUniquePropertyForUserTypeA)
UserTypeB(id, email, firstName, lastName, profilePicture, someUniquePropertyForUserTypeB)
What would be a scalable approach to achieve this? I am also using AWS Amplify authentication so I can save the common data as CustomAttributes offered by Cognito, but then how would I save the uniqueProperties for the two user types. Will this approach scale?
This is a social app and is heavily reliant on other users' profile data as well (which will be queried most of the time).
Check out the patterns that are recommended by AppSync (The graphQL service that is behind Amplify when adding graphQL API). It is described in detail here: https://docs.aws.amazon.com/appsync/latest/devguide/security-authorization-use-cases.html
The main idea is to have multiple user pools defined in Cognito and then you can use the different groups in the resolvers. For example:
// This checks if the user is part of the Admin group and makes the call
#foreach($group in $context.identity.claims.get("cognito:groups"))
#if($group == "Admin")
#set($inCognitoGroup = true)
#end
#end
#if($inCognitoGroup)
{
"version" : "2017-02-28",
"operation" : "UpdateItem",
"key" : {
"id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
},
"attributeValues" : {
"owner" : $util.dynamodb.toDynamoDBJson($context.identity.username)
#foreach( $entry in $context.arguments.entrySet() )
,"${entry.key}" : $util.dynamodb.toDynamoDBJson($entry.value)
#end
}
}
#else
$utils.unauthorized()
#end
or using the #directives on the graphQL schema, such as:
type Query {
posts:[Post!]!
#aws_auth(cognito_groups: ["Bloggers", "Readers"])
}
type Mutation {
addPost(id:ID!, title:String!):Post!
#aws_auth(cognito_groups: ["Bloggers"])
}
...
This is a Database design problem. To solve this, you can try creating a relation that has the common attributes in it, that is, User with attributes, (ID, email, firstName, lastName, profilePicture, someUniquePropertyForUserTypeA).
After that, create sub-classed based relations, that is UserTypeA, and UserTypeB.
These relations will have a unique ID, and have a foreign key relation with the parent (User). How? The first major relation would be 'User'. The 2 sub classed relations would be 'UserTypeA', and 'UserTypeB'.
The 'User' has an attribute 'ID'.
So the two sub classes have an attribute, 'User_ID', which is a foregin relation to 'User'.'ID'.
Now just autogen another ID column for UserTypeA and UserTypeB.
This way, you have a central table which has a unique ID for all users, and then you have a unique ID in each of the sub class relations, which together with User_ID forms a composite key.
Consider a snippet:
glueContext.getSinkWithFormat(
connectionType = "postgresql",
options = JsonOptions(Map(
"url" -> "jdbc://myurl",
"dbtable" -> "myTable",
"user" -> "user",
"password" -> "password"
))
).writeDynamicFrame(frame)
This creates table if not exists automatically, but without any idexes or id columns. Is there a way to setup a glue to
create them?
Does AppSync support nested single mutation?
I want to call a single mutation which will insert records into two tables, eg: User and Roles tables in DynamoDB.
Something like this for example:
createUser(
input: {
Name: "John"
Email: "user#domain.com"
LinesRoles: [
{ Name: "Role 1" }
{ Name: "Role 2" }
]
}) {
Id
Name
LinesRoles {
Id
Name
}
}
Do I need to create two resolvers in AppSync for User and Roles to insert the records in both tables?
I can think of three ways to achieve this:
Use a BatchPutItem to save records into two tables at once. However, you won’t be able to use any ConditionExpression
Use a pipeline resolver with two AppSync functions where one function makes a PutItem to the Roles table and the other to the User table. However, you need to be ok with potentially inconsistent scenarios where the record has been inserted in one table but not in the other.
Use a Lambda resolver that does the write to 2 tables inside a DynamoDB transaction.
I have User and Buyer participants on the network. Generally, the buyers cannot READ the user's data but I want to make GrantAccess and RevokeAccess transactions so the Users to have the option to grant and revoke the READ access from Buyers
I haven't been able to find anything on how to do this, would appreciate any help.
You would run a 'tx_GrantAccess' transaction that firstly, updates a particular BUYER's record (eg. id buyer123 - a participant modeled with a field called access, which is set to true by this transaction).
I can use a condition match (as a boolean) on the target BUYER records (resources) and if the BUYER, say buyer123 (ie that's accessing the business network) has access=true then he can READ the USER records.
Transaction rule (needed by User to access the transaction classes)
rule rule_1 {
description: "grant access to User, for the 2 x Transactions themselves"
participant: "org.acme.example.User"
operation: CREATE
resource: "org.acme.example.tx_*"
action: ALLOW
}
User Access rule:
rule rule_2 {
description: "if granted access, allow READ of User by buyer"
participant(m): "org.acme.example.Buyer"
operation: READ
resource(v): "org.acme.example.User"
condition: (m.access)
action: ALLOW
}
where Buyer has a field (eg.
participant Buyer identified by id {
o String id
o Boolean access default=false
}
and your transaction tx_GrantAccess has a function that will set access to true on a particular Buyer's record and tx_RevokeAccess will set it to false etc.