How do I model a 1:N relationship that is constrained a by third entity? - erd

My predicament: I am Chen-modelling an accounting database in which the client to account entity relationship is one-to-many (1:N), but the client to office_location relationship is unique (one-to-one, 1:1). I've tried figuring a ternary relationship and also resolving it into a weak entity attached to the other three through binary relationships. I end up with something like this:
OFFICE_LOC ---SERVES(M:N)=== CLIENT
OFFICE_LOC ---ANCHORS(1:N)=== ACCOUNT (WE)
CLIENT ===OWNS(1:N)=== ACCOUNT (WE)
I am having a tough time figuring out how to model the condition that a client can have only one account per office_loc even though they can have many accounts, generally speaking.

I don't know if your asking specifically how to model something in Chen modelling (which I know NOTHING about) or if you're asking how to data model this relationship. If the former ignore this answer, if the latter...
Client <---Client_2_Account---> Account
The Client_2_Account many-to-many table will have an Office_Location fkey field in addition to the fkey fields for client and account. Put a unique constraint on the compound key of client/office_location and a unique key on account. Then a client can have only one account record for an office location and each account record can be owned by only one client.

Related

Are multiple dynamoDB queries in a single API request bad practice

I'm trying to create my first DynamoDB based project and I'm having some trouble figuring out the best practices working with a NoSQL database.
My usecase currently is storing users and teams. I have a table that has a partition key of either USER#{userId} or TEAM{#teamId}. If the PK is TEAM{#teamId} I store records with SK either TEAM#{teamId} for team details, or USER#{userId} for the user's details in the team (acceptedInvite, joinDate etc). I also have a GSI based on the userId/email column that allows me to query all the teams a user has been invted to, or the user's team, depending on the value of acceptedInvite field. Attached screenshots of the table structure at the moment:
The table
The GSI
In my application I have an access pattern of getting a team's team members, given a user id.
Currently, I'm doing two queries in my lambda function:
Get user's team, by querying the GSI on PK = {userId} and fitler acceptedInvite = true
Get the team data by querying the table on PK = {teamId} and SK begins_with USER#
This works fine, but I'm concerned I need to preform two separate DynamoDB calls in my API function.
I'm wondering if there's a better way to represent this access pattern and if multiple dynamoDB calls are actually that bad, since I cannot see another way to do this.
Any kind of feedback is appreciated!
The best way to avoid making two queries like this is to supply the API caller with all the information needed to make a single DynamoDB request. For your case this means supplying the caller with the teamId. You can do this as either as part of a list operation response, or if it is the authenticated user, then as part of their claims in a JWT.

Oracle APEX User Rights and Previleges

I do not have much experience and I would like to know if there is an easy way to create user rights and privileges, so that each user can access only specific records from the database tables, based on the level he belongs to.
More specifically, suppose we have a group of companies where this group has some companies and these companies have some branches and the branches have some users.
I want the user belonging to the "group of companies" level to have access to and view all the entries in the database related to that group and what is below it (its companies and the branches of these companies).
The user who belongs to the "company" level should have access and see only the files of this company and the branches that this company may have in the database.
The user belonging to the "Branch" level should only be able to access and view this barnch records in the database.
And finally the user belonging to the "End User" level to have access and see only the records created by the user in the database.
Of course level "administrator" will have access to all records in the database.
I thought of creating a user table with a field "User_Level" and in each table to enter USER_ID where based on this I can find the level of a user but how can I restrict access based on the Group of Companies or the Company or the Branch where it belongs?
In APEX you can create authorization schemes to determine what components a user has access to within an application - but that is just a part of the answer to this question. Your question is about filtering the data that is showed to a user based on certain criteria.
There are a couple of possible solutions to this. Since this is a very broad question I'm just going to give you pointers/concepts to start your research. Up to you to determine what solution/combination is most suitable for your implementation.
Concept: Multi-Tenancy
If the data is used by multiple tenants then add a tenant_id to each table that has tenant specific data. In your case a tenant should be a branch. A simple design could be a groups table (to hold branch - companies - company groups), a group_members table (to define relationship between branch - companies - company groups OR between any group and a user) and a users table.
Concept: VPD This is a feature in the oracle database that allows a transparent implementation of security rules. In the application you'll define a simple select like
SELECT * FROM emp
But the VPD implementation will automatically add a where clause to the query to only show the records defined in the VPD policy. This makes developing the application a lot easier since there is less room for errors. Note that this database option could not be included for your licence. There is also something called "Poor Man's VPD" that does not use the VPD option. Google on how to implement this in your apex application.
Just do it all by hand: This is the least preferred option but it can be done. For every component where a select is done, manually add a where clause to restrict the returned rows. However this is very maintenance intensive and there is a ton of room for errors - obiously the data model will still have to support the striping of the data.
This blog post by Jeffrey Kemp might give you some pointers as well: https://jeffkemponoracle.com/2017/11/convert-an-apex-application-to-multi-tenant/ - go through the "further reading" section at the bottom.
you can create a procedure or function and in your app's shared components -> authorization scheme use that such as pl/sql function/procedure returning boolean and return true for the users you want to see the things and false for hiding.
In Apex components, select this authorization scheme like in items, pages etc.

Implement authorization in SOA

I have a question abut what is the best practice/pattern to ensure proper authorization in my SOA application. I have a bunch of services that allow users access certain data (stored in DB). An example of a typical scenario is...
We have a EMPLOYEE table that has say a one to many relationship with PROJECT. So AN EMPLOYEE can have many PROJECTS. Also each employee belongs to a region. The users of the system are allowed to edit information on employee and projects. However Each user only manages data for a few regions and therefore can only modify employees and their projects that belong to a region that the user manages. So user may have access to regions A, B, C and can edit employee/project data for Region A employee but not region Z employee.
I have one service that lets you edit an employee and another to edit an project. Similarly a project has relationships to other entities, for e.g. SCHEDULE, and I have services to edit those as well.
However my problem is this -- whether an user can edit or not a project or schedule, by calling the corresponding service, is determined by which region the employee (to which these projects and schedules are related) belongs to. So for every service to modify a project or schedule or any entity in that hierarchy of data starting at employee, I am having to query the corresponding employee and enforce the region constraints. Which can become very expensive operation considering the database calls and number of joins (my real example has lot of such entities and corresponding services) I have to make on every service call. Is there a more elegant light weight solution for my scenario?
First of all, I'd call these requirements regular business rules rather than authorization. Authorization is usually much more generic in nature, meaning whether a user is allowed access to a specific system or is allowed to invoke a certain function (regardless of parameters).
Second, and based on a business rules view, you should take into account the consistency needs around these business rules before dividing things up into services.
Third, relating to your statement "my real example has lot of such entities and corresponding services", it usually not a good idea to have services that correspond to entities.
So, in summary, you need to redesign your service boundaries such that the rules that need to be enforced (in a highly consistent manner) are contained within a single service. One way to do that is to take different parts of a given entity and put them in different services - provided that there aren't any business rules that demand consistency across those diffe

Peoplesoft OPRID include in PERSON_BASIC_FULLSYNC Message

Some query regarding OPRID. i want to include the oprid in the Person Basic Fullsync message. I added the record PSOPRDEFN to the Message. But i am not able to get OPRID values for all the employees. I am getting only for some employees whose user profile is present.
Is OPRID related to only for user profiles?
how can i generate OPRID for all employees??
In PeopleSoft you have persons (identified by EMPLID) as transactional data, and users (identified by OPRID) who can access the application.
Not every user is necessarily related to a person or employee (e.g., system accounts such as PTWEBSERVER, developers' accounts, etc.), and not every person or employee will have a user profile (e.g., employees without access to Self Service transactions, ex-employees who no longer work at the company, etc.).
So, to answer your questions:
Yes, OPRID is only related to user profiles (you can obviously find OPRID values used elsewehere, like in "Last Updated By" fields, security tables, etc., but it only relates to users). Often an OPRID will be linked to an EMPLID (in the PSOPRALIAS and/or PSOPRDEFN tables), but this is neither guaranteed not required.
Generating a user profile for every employee is not always warranted, as there are important security implications to it. Furthermore, if your company uses single sign-on with LDAP authentication, the users are automatically created upon first sign-on if so authorized, so proactively creating them is unnecessary and often ill-advised. Finally, it will often be a security breach to have ex-employees with active user profiles, so you may never truly reach a scenario where all your EMPLIDs have associated OPRIDs. If you've weighed all of these concerns and do indeed want to pre-populate the entire user population, you can use something like Excel-to-CI. However, note that this will solve the issue as of right now, and the moment you create a new employee you'd need to also create its user profile.

asp.net mvc3 user roles and access rights

In my ASP.NET MVC3 application, I am having users, roles and entities. User Roles will be having access to entities. So while storing users and roles in database which of following is good approach?
To store user list in the entity tables
Entity Ids in the user table.
In future the number of entities may increase to 1000,10000 so I want to consider the performance aspect also.
I think the relationship between Role and Entity is many- to many. One role can have zero or more entities and one Entity may belongs to zero or more Role. So create a third table to store those with 2 columns, RoleId and EntityID
Sample data would look like
ROLE_ID ENTITY_ID
-----------------------------------
1 144
1 146
2 194
4 14
4 194
Dependent upon the granularity of control you need for your application you may want to consider the model used in Windows Identity Foundation (WIF) which is now part of .NET Framework 4.5. This is a claims-based architecture and the term that is used for what you are calling Entity is Resource. What differs from your model is they also have the concept of Operation. A Resource can have many Operations, and a typical Operation would be something like read, write, execute. This is where the finer granularity of control comes in.
So in this case an Operation for a particular Resource can have many Roles and a Role can have many Operations, requiring another table to map this many-to-many relationship. Use of int for a primary key in Roles and Operations as object ID's is good for performance. User's can have many Roles and Roles will have many Users, so once again you will need another table to manage this many-to-many relationship.
So the answer to question 1 is you do not store the User list in a the Entity table. You have a separate User table that maps to table of Users-To-Roles, which maps to Roles, which maps to Roles-To-Operations, which maps to a table of Operations, which maps to table of Resources. If you do not need the granularity of Operations eliminate that table and map your Roles to Resources via another table to handle this many-to-many relationship.
The answer to question 2 is no, you would not have an Entity (Resource) ID in the User table. A User is mapped to a Resource via the relationships I have described above.
The best approach for using this model and the full extent of the claims-based architecture is to not assign Roles to your methods using the AuthorizeAttribute, which is how it was typically done in the past. Instead assign Resource and Operation to your methods which decouples your security policy from your application. For a model of this approach look at ClaimsPrincipalPermissionAttribute. You can create your own custom AuthorizeAttribute that uses this approach.

Resources