Extending AccessInfo to Include Roles - acumatica

I'm looking to extend the base Singleton "AccessInfo" to include additional information pertaining to the current user (such as roles.)
Is there a most favorable path to do this? I can see how to extend a Graph, Cache, but not seeing any documentation how to extend this area.

Unfortunately due to the way it has been implemented, there is not a way to add fields to that DAC and have them populated on instantiation, and since it's not selected from the DB like a normal DAC, I do not think events would fire for it.
If you would like to access Roles related to the current Users, this should suffice.
PXSelect<UsersInRoles,
Where<UsersInRoles.userName, Equal<Current<AccessInfo.userName>>>>.Select(this /*Or Base if it's a Graph Extension*/);
As there will likely be multiple Roles per user, you will need to loop.
foreach (UsersInRoles role in PXSelect<UsersInRoles, Where<UsersInRoles.userName, Equal<Current<AccessInfo.userName>>>>.Select(this /*Or Base if it's a Graph Extension*/))
{
//Some thing here
}

Related

Customizing users and roles using identity in asp.net mvc 5

I have sample project for identity customization using
Install-Package Microsoft.AspNet.Identity.Samples -pre
command. But, for this project I have a general ApplicationUser class representing all the users of my application. What if I have different categories of users. For example, I may have Teacher and Student entities and data representing both the entities will be different. How can I customize my application to store data for both the entities having all the features of ApplicationUser?
One way that I think is inheriting both the classes from ApplicationUser and then doing appropriate changes in IdentityConfig.csand defining Controllers for each of them. Is there any other efficient way of doing this?
What if I want to use the built-in authentication and authorization features but using database first workflow?
First, you want to know how to create "types" of users. The way you would do that is exactly how you expected: inherit from ApplicationUser. By default, this will result in a single "users" table with an additional Discriminator column. This column will store the class type that was persisted, i.e. "Teacher", "Student", or "ApplicationUser", and EF will utilize this information to new up the right class for each particular record.
One thing to note with this, though, is that you need to be aware of how UserManager works, namely that it's a generic class (UserManager<TUser>). The default AccountController implementation you have from the sample defines a UserManager property on the controller which is an instance of UserManager<ApplicationUser>. If you use this instance with something like Teacher, it will be upcast to ApplicationUser. In particular if you were to do something like UserManager.Create(teacher), it will actually save an ApplicationUser, instead (the Discriminator column's value will be "ApplicationUser", rather than "Teacher"). If you need to work with the derived user types, you'll need to create separate instances of UserManager<Teacher> and UserManager<Student> for that purpose.
Next, you want to know if you can use a "database first workflow". To answer that, we need to define exactly what that means. EF has what it calls "Database First" which employs EDMX to represent your database entities. This in particular is incompatible with Identity. However, despite the name, what EF calls "Code First", can work with an existing database just as well as create a new one. In other words, yes, you can use an existing database, if you prefer, but no you cannot use "Database First", in the EF-sense. For more information about using an existing database with Code First, see my post.

User roles and workflow status xpages and managed bean

To not have to keep repeating some validations, for example, who can see a button in a certain status of a document in the worlflow, I'm using session, scope, and session variables to store the user roles and application variable to store the Status related to each area.
I was evaluating whether it would be better from a performance and build point of view to implement a managed bean, to return the user roles and the possible statuses of each participating workflow area. Would it be the best structure in fact? What do you think? I do not have much experience in java. How could I construct the structure in java, several methods, one for roles and the other for set of status associated with the area that would name the related method? You could return the results of this method in arrays, or there is a better return structure.
Thanks a lot!
My best suggestion is to adopt the pageController Methodology. Then it's more like true MVC. This has been talked about on NotesIn9 screencast many times but basically you have a java object that's bound to your XPage. In effect it's a viewScoped bean that holds all your page logic. Then you can have methods like isGroupMember(), hasRole() etc and calculate that on the pageInit. There's little need to hold onto that in sessionScope in my opinion. So for example I have this in my pageController :
public boolean isGroupMember(String groupName) {
return JSFUtil.getXSPContext().getUser().getGroups().contains(groupName);
}
So that's available to each page. BUT I don't need to copy that snippet onto every page controller. In Java you can have your page controllers extend a more generic class. so I have a "base.pageController" class. All the specific page controllers extend that. So this isGroupMember() code goes into the base and then it's available to be used on every XPage. Doing it this way gives you the ability to have generic functions like this and then hold more specific function that are only for the individual page.
You can also have a hasRole() function etc...
Recommend you check out this video : http://www.notesin9.com/2016/08/25/notesin9-196-no-dependency-page-controllers/
Also for a question like this, I recommend you just use the xpages tag. Adding others like javabeans can bring people in who know nothing about XPages and XPages is unique enough of a beast that outsiders can cause some confusion on occasion.

How and when to hydrate domain objects in the CQRS command stack

Suppose I have a command that saves an application Role along with some application Permissions. My roles and permissions have (or will have) business rules, so I'll use domain objects:
class Role {
...
IEnumerable<Permission> Permissions { ... }
AddPermission(...)
...
}
class Permission {
...
int ID { ... }
string Foo { ... }
string Bar { ... }
string Baz { ... }
}
When I'm saving a Role, I need a full Role object and will probably receive everything I need from the presentation layer. I do not need full Permission objects, though, because I only need to associate their ID with the Role. I don't need the Foo, Bar, and Baz properties.
When I'm saving a Permission, I obviously need the full Permission object.
My Question: What is the right way to handle that Permission object? If I only have one Permission class, then, when I'm saving a Role, I will either:
Have to query/hydrate full Permission objects from the database so the Role has legitimate Permission objects in its collection, or
Attach incomplete Permission objects (IDs only) to avoid the trip to the database.
Option #1 sounds like the kind of command/query complexity CQRS aims to avoid, and #2 sounds like an invalid object floating around--I don't even want to be able to create invalid objects, much less use them.
I could also create a PermissionSummary class and the full Permission class derives from it. I've done this before, and it inevitably leads to a creep of properties from the "full" class up to the "summary" class.
Batavia's response to CQRS is great and as I have no experience with that pattern Ill try and answer the 'what do I save' question.
The answer to this one depends strongly on your Model design and the proposed behavior of the Permission entities. DDD does not work without a strong knowledge of the business domain.
Having said that I can think of 3 scenarios:
1) Permissions are immutable and Roles get changed. In this scenario Role becomes the aggregate root and the collection of Permissions in re-hydrated on each fetch. The properties and methods of each Permissions entity is available to Role entity enabling operations like
partial class role() {
public enumAccessType AccessToAction(enumAction action) {
foreach(var p in Permissions)
if p.HasFullAccess(action) return enumAccesssType.Full;
foreach(var p in Permissions)
if p.HasLimitedAccess(action) return enumAccesssType.Restricted;
return enumAccesssType.None;
}
}
There is a Permission repository for saving new Permissions and a Role Repository for maintaining the roles and the role_Permission tables
NOTE: Just because the domain object has the full PERMISSION objects doesn't mean that the persistence layer needs to update the PERMISSION table for each of the permissions added. The RoleRepository should only update ROLE (roleId, roleName) and ROLE_PERMISSION (roleId, permissonId) tables.
2) Permissions are mutable But roles are static. In this situation is may make more sense for your model to have Permission as the Aggregate root and a collection of Roles as role is just a bucket for grouping Permissions:
class Permission {
Ienumerable<RoleId> Roles {get;private set;}
PermissionId ID { ... }
string Foo { ... }
string Bar { ... }
}
Again there is Permission repository for saving new Permissions and maintaining the Permission-Role relations. The Role Repository just handles roles.
3) Roles and Permissions change all the time - your security requirement is complex and will difficult for most end users to comprehend. Bring in the Domain Expert to explain how Role and Permissions relate and affect the rest of the system and WHY the have to be so flexible. Look at the why and try and identify processes or behavior that may be incorrectly being forced into a roles-permissions pattern. This will probably require its own bounded context and services to work.
It helps to remembers 'Database Tables' != 'DDD Entities' != 'User Interface'. At first blush it looks like your coming at this from a database design point of view rather than the domain behaviour point of view.
A big 'Am I Doing This Right' is this check: If I save changes to one entity , do I need to reload any other entities that reference that original entity in order for those other entities to work? If the answer is yes then you need to revisit your model.
so when using CQRS i think the answer is neither.
I think it's important to differentiate between DDD and CQRS.
When saving a role (In the CQRS pattern) you would be sending a "RoleChangeRequest" command to your backend. This would then raise a RoleChangeRequested event. (this could be done by a domain service, possibly even by the domain layer itself). This event would be handled by your database layer but this event would look more closely to this
class RoleChangeRequested {
IEnumerable<int> PermissionIds {....}
string name {....}
}
The key here is that in raising the event that would save your data you only need to know about the Id's of the permissions. There is no need to either query permissions (ok, maybe you want some check that they actually exist. but a foreign key relation could handle this). or to attach incomplete objects.
NOTE: In just this example CQRS is going to make your application a lot more complex. CQRS is weapons-grade architecture and should be handled with extreme caution. Now why would you want to use CQRS, that's because your next requirement is to make a full and guaranteed audit trail of all your role and or permission changes. This is just another event handler to the same events. And you could even have an event handler to the generic ievent interface and then you are guaranteed that you audit every event being raised in the application. That you get (almost) for free and is why CQRS can be a benifit.

Retrieving a value object without Aggreteroot

I'm developing an application with Domain Drive Design approach. in a special case I have to retrieve the list of value objects of an aggregate and present them. to do that I've created a read only repository like this:
public interface IBlogTagReadOnlyRepository : IReadOnlyRepository<BlogTag, string>
{
IEnumerable<BlogTag> GetAllBlogTagsQuery(string tagName);
}
BlogTag is a value object in Blog aggregate, now it works fine but when I think about this way of handling and the future of the project, my concerns grow! it's not a good idea to create a separate read only repository for every value object included in those cases, is it?
anybody knows a better solution?
You should not keep value objects in their own repository since only aggregate roots belong there. Instead you should review your domain model carefully.
If you need to keep track of value objects spanning multiple aggregates, then maybe they belong to another aggregate (e.g. a tag cloud) that could even serve as sort of a factory for the tags.
This doesn't mean you don't need a BlogTag value object in your Blog aggregate. A value object in one aggregate could be an entity in another or even an aggregate root by itself.
Maybe you should take a look at this question. It addresses a similar problem.
I think you just need a query service as this method serves the user interface, it's just for presentation (reporting), do something like..
public IEnumerable<BlogTagViewModel> GetDistinctListOfBlogTagsForPublishedPosts()
{
var tags = new List<BlogTagViewModel>();
// Go to database and run query
// transform to collection of BlogTagViewModel
return tags;
}
This code would be at the application layer level not the domain layer.
And notice the language I use in the method name, it makes it a bit more explicit and tells people using the query exactly what the method does (if this is your intent - I am guessing a little, but hopefully you get what I mean).
Cheers
Scott

Can required WCF4 DataMemeber's be organized into required groups?

Is there a way to have required DataMember's within a DataContract to be organized into groups so that you really only require group one or group two but no both to be provided?
I am looking to see if there is functionality similar to Workflow Activity validation where you can flag InArgument's with a RequiredArgument and then use OverloadGroup attribute to put these into groups so that only the arguments in one of the specified groups are required.
It is not possible out of the box with DataContractSerializer but you can switch to XmlSerializer and use xsd:choice (XmlChoiceIdentifierAttribute) but be aware that this will affect your data class beacuse this construct has its own requirements.
Nope, there is no way to do this. Only way to group is to have two different classes and extract away members/properties into those classes, but still...you won't be able to dictate an "either-on" setting.

Resources