I'm currently evaluating spring ACL for a web project. The domain model (JPA) of the project consists basically of a hierarchy starting with Company -> Client -> Product and so on. Users (which are members of a company) of the app are only allowed to see Products which belong to their Company.
I don't see any other way than assigning each Company it's own Role (e.g. ROLE_COMPANY_A, ROLE_COMPANY_B, etc), which is persisted more or less hardcoded in the ACL-tables (This is most probably not the best design; open for suggestions...)
While I was able to hook up the Spring ACL with the JPA Layer (Aspect on the various Repository's save()-Methods), I have troubles finding the proper parent ACL Object when inserting a new Entity. To find out to which Company an Entity belongs I must traverse the Object-hierarchy to find the proper Role (i.e. ROLE_COMPANY_A) within the Aspect (which is even worse, since an Aspect should not contain any app-knowledge).
So the question is, if anyone has used spring ACL in a scenario like this one? Since we are not bound to spring ACL, another solution/framework may also be considered. Bascially I really want to avoid the traversal of the object hierarchy to find out the proper Role.
tnx & regards
Related
I have embedded Teiid 12.3 in a Spring Boot application. I want to get into the metadata of my VDB in order to generate a diagram using graphviz-java. I assume that if I have a org.teiid.metadata.Table object, I can call getIncomingObjects() to get references to tables that table depends on. I just can't figure out how to navigate from the EmbeddedServer to the Table objects.
I looked into using the administration API available via EmbeddedServer.getAdmin(). From there, I can call getVDBs(), and from there I can navigate down to getModels(), but below that level there is only the model source via getSourceMetadataText(). I also tried subclassing EmbeddedServer to make getVDBRepository() public. I can call getVDBRepository()*.getModels(), but it returns the same Model objects only get me access to the source definition of the models, not the runtime metadata model.
I tried getVDBRepository().getSystemStore() and VDBRepository.getODBCStore(), but those MetadataStores are not for the VDB I have deployed.
I haven't found any examples by Google, Teeid JIRA, Teiid forum, or StackOverflow to help me.
Take look at [1] the getSchema method on Admin API, this method returns the string form of the metadata, however you can grab Schema object for object form. If you do not want that way, Teiid also exposes system catalog using many SYS tables, you can issue SQL queries to grab the metadata of schemas and schema items in a VDB. One for internal access, another is from external access.
BTW one of users created a dependency diagram tool that may be useful if you are trying to do something similar. See [2]. Let me know if you interested in pushing that further.
[1] https://github.com/teiid/teiid/blob/master/runtime/src/main/java/org/teiid/runtime/EmbeddedAdminImpl.java#L544-L557
[2] https://github.com/teiid/metadata-catalog-ui
If i had an additional Spring application extending my Magnolia, which gets some Java Object, which will be used inside my application, how can i save it ???
I already learned to do queries, but i cannot use it yet to put something in or change it. I can only fetch data. into nodes.
where or how do i persist ??
For Info: I have a repository which shall store the special data and i have a nodetype declared for this. As it is now the spring social UserConnection i have the workspace "connections" with nodeType mgnl:userConnection
My JavaObject is a UserConnection, designed near to MgnlUser, so i also add properties, but i don't know yet, what to do with path and uuid.
i don't know yet how to declare it or where to get it.
You can store the data same way as you fetch it. Assuming you are running your spring app through Magnolia filter chain you have MgnlContext setup for given thread and can easily call MgnlContext.getJCRSession("connections") to obtain the session and node same way you do to retrieve your data, to add subnodes or set properties on given node you just call node.addNode("myNewNode") or node.setProperty("myProp", "newValue") on the node and follow that with call to session.save() to persist the session info. But I guess you already know all that.
If you want to get whole object serialised into repo for you by system instead, you can use JackRabbit OCM for this, or even easier - use integration of OCM into Magnolia - http://jira.magnolia-cms.com/browse/MJROCM
. It's already used in Shop module of Magnolia if you are looking for examples on how to work with OCM.
HTH,
Jan
In a SPA app using breeze, how would I go about combining metadata from multiple sources for related data so that I can use them in 1 manager on the client. For example, I might have the following
Entity Framework Metadata from WebAPI controller (e.g. Account)
Custom Metadata from DTOs (e.g. Invoices)
Data from a third party service with metadata provided from client side metadata (e.g. Invoice transmission result)
In each case the data has related properties so I might want to be able to use Account.Transactions.TransmissionResults
UPDATE
I have tried several ways of getting this to work but to no avail. From Jay's answer, it is not possible at present to update the metadata from the server once it has been retrieved, so if and until that changes (see breeze user voice issue) I am left with one of the following approaches
1 Retrieve metadata from the server from Entity Framework and add metadata on the client to add extra entities. This worked to a degree but I could not add navigation properties from entity types added on the client to entity types retrieved from the server because I cannot add the foreign key association to the entity retrieved from the server, again back to the need to modifying metadata after it has been retrieved.
2 Write the complete metadata by hand, which will work but makes maintainability that much harder and seems wrong to be manually writing mostly the same code that the designer would write.
3 Generate most of the code from Entity Framework as described in the docs and then update it afterwards to add in the custom entities. Again similar issues than with option 2, it seems hacky.
Anyone else tried something similar? Is there something I am missing, which I could be, I've only started with breeze and js.
Thanks
A breeze EntityManager can have metadata from any number of DataService endpoints, and you can manually add metadata (new EntityTypes) on the client at any point. The only current restriction is that once you have metadata from a specific service, you can't change it. ( We are considering reviewing the last restriction).
So the question is, what are you trying to do that you can't right now?
I am struggling with solving how to handle insertions and deletions with MVC3 and the Entity Framework 4.2
My Setup:
Website accesses my Service Layer, which uses the Repository Pattern to fetch and return my Model(POCO) objects. The Solution is separated into the following projects:
DAL(Data)
BAL(Service layer in here)
MODELS (Poco objects)
WEBSITE (presentation)
My Problem:
I need to be able to control the adding and deletion of objects and run whatever business logic I like. This should be done in the Service Layer.
Example of Problem: I have an Account class with an ICollection of AccountContact objects. Each AccountContact object has an ICollection of PhoneNumber objects. What I envision is a Service method something like this
AddAcountContact(Account account, AccountContact accountContact){
//Run business logic to ensure that this account contact can be added
account.AccountContacts.Add(accountContact);
unitOfWork.SaveChanges();
}
DeleteAccountContact(Account account, AccountContact accountContact){
//Run business logic to ensure that this account contact can be deleted
account.AccountContacts.Remove(accountContact);
unitOfWork.SaveChanges();
}
Unfortunately I have no way to force adding and removing through my Service class. A developer could easily insert/remove directly from the presentation layer. Anyone have any ideas or know common solutions to this problem? Perhaps I am doing something wrong....
If you expose class with public collection property allowing Add and Remove you are telling developers that they can call those methods. You can define the coding policy and use code review to check that policy is followed but it is only workaround. Still anybody could forget about that and call Add or Remove directly because your classes are wrongly designed.
The main problem here are entities exposed directly to UI. If you don't want direct modification of entities in UI layer simply don't expose them to that layer. Use another type (DTO / View model) with readonly collections exchanged between service layer and UI layer and convert that type to entity inside service layer. Another option is adding validation directly to entities or custom collection types.
I wanted to get your opinions on the easiest way to track changes that users make when they do CRUD events. I am working on a system where the users are less interested on permissions, but really want to have a sophisticated log of what changes a user made. I am using ASP.NET MVC 3, EF, and NLog.
Any advice is greatly appreciated :)
Steve
I use a convention based approach. Each entity has an associated audit entity which includes all properties from the base entity plus information on the change, including whether it was successful or not. I override the SaveChanges method on the DB context. For each entity being changed it creates an audit entity from it holding the new values. It attempts to save the changes, then uses a separate, auditing context to save each of the audited entities with the results of the save operation. I use an injected utility in the data context to get access to the current user (via HttpContext.Current for web, via the Environment.User for non-web) when constructing the audit entities.
I blogged about an earlier version of this for LINQ to SQL at http://farm-fresh-code.blogspot.com/2009/05/auditing-inserts-and-updates-using-linq.html. You should be able to get the basic idea from that.