This is my current understanding of the events on pressing the Activate button:
If the user has replication permission, the content is sent to the dispatcher.
If the user does not have replicate, the Request for Activate workflow is run. Out of the Box this performs two steps which are both sent to the Administrators group.
If I change the OOB Request for Activation workflow to assign to another group then this group gets the message in their CQ Inbox instead.
My requirement is that I have multiple websites belonging to different divisions within the company, meaning that each has separate groups for users who can only author content and users who can Approve/Activate that content. In one case there is an additional requirement for the content in the careers section to be approved by the HR team only.
How can I alter the workflow to achieve these requirements?
I can think of two ways of doing this:
1) Change the OOB box workflow to use OR steps to switch to differnt groups based on the content path. This could get very complex when dealing with pages for both pages and assets, and the special conditions like the careers example.
2) Create a custom step that runs Java code that uses the AccessControlManager class to look for replicate permissions on the node, and if there aren't any then to traverse up the tree until it finds a node with permissions.
I've gone with option 1) for a similar problem.
If your main concern is having too many branches in your OR Split, maybe there's an opportunity to break down the workflow's decisions into multiple steps, instead of having one decision point where it branches out to many different paths.
For example, you might first split by what site the payload is on, and then split again based on user type, or section of the site. So, something like:
site 1
section 1
role 1
role 2
section 2
site 2
... and so on, where each level of indentation represents a separate OR Split.
If you use the Container Step to trigger a sub-workflow at each of these decision points, that may help keep your workflow more organised.
Because I didn't love the idea of changing the OOB Request for Activation workflow, I minimised that by making the first step an OR Split that does a generic check - basically:
Pseudo-code:
if (we're in one of the sites that's subject to my custom workflows) {
Container step that points to my main custom workflow;
} else {
Continue with the default Request for Activation workflow steps;
}
That way you make minimal changes to the OOB workflow, and leave yourself open to running the default workflow if you set up a new site on the same instance, and don't want it subject to your custom workflow.
We've created a custom property in each page, "page owner", which in fact is a pointer to a group (I wish we have made it inheritable through the tree since beginning). Then workflow was customized so that page owner group receives this in their inbox for approval.
Related
these days I’m facing a fundamental problem – let’s call it an architectural design decision.
So my team and I build typical line of business (lob)-web-applications for my company. For my purpose, lob means especially this:
A lot of user-interaction (entering data, CRUD entities, display data, aggregating data, statistics and reports, validation and so on)
Very restrictive (users have to login, users have different permission-levels, they can make different kinds of changes on different entities, display various reports and so on)
For an example, let’s take an ordinary approval-workflow: I need a new laptop, so I go to the “ressources-webApp” and create a new purchase requisition. My boss gets a notification and has to approve my request. In the next step, the proper department has to buy the laptop and finish my requisition.
I know this is a simple “hello world”-example and in real life you would use an existing software for this purpose (SAP or something like that), but it describes my use-case pretty well: data-driven and very restrictive (I can see all requisitions of my department but only change or delete my ones, I should not see the page for the approval or call the approval-api, my boss should only see the requests of his employees but not for the empolyees of another department, neither my boss nor I should see the page or be able to finish a requisition and so on).
Currently we are using ASP.NET MVC and WebAPI in combination with angularjs 1. For each “action” (page or view) exists a mvc-controller which listens to a specific route and returns the appropriate view. Each view references a specific angular-controller. Also each view may consist of different “partial views” (components or controls). To handle data the angular-controller calls webAPI-controllers which also listen to specific routes and handle the request (GET/POST/PUT/DELETE). Each controller (mvc and webAPI) checks the authorization-token of each http-request which comes in a cookie, if the user is allowed to open the page or call the action.
Now I’m wondering how to do this in a SPA-application with angular 2. Angular 2 sounds pretty interesting for me and has some nice benefits over angular 1, so I want to try angular 2. It seems that with angular 2 you only can build a SPA-application (compared to the “classical” MPA-application I mentioned above, where every page comes from the server and contains a angular-controller).
Generally I’m not disinclined to SPA, but I’m not sure how to handle the security-questions mentioned above.
In addition there are other common problems with SPA: not working back-buttons from the browser, no way to enter a specific url directly to the browser, no bookmarking etc.
So, do you have any advice, tip or best practice for me? Do you think that SPA is a good “pattern” for lob-web-applications? And if yes, how would you handle the security-problems as well as the other common SPA-problems?
Best regards,
Alex
I'm designing a small application using Symfony2, with a DDD domain conceived as a vendor. This allows me to abstract my domain by not making any assumptions on what uses it. Basically, this domain is a set of business entities and services which perform their internal stuff. The business operations are called from the outside (Symfony controllers) by simple facades that do not expose anything from the domain.
Now, I would like to test my domain to validate its business rules. Given that this domain can't work on its own as it needs concrete repositories implementations, I set up my tests to use mocks of these repositories. My question is : how can I validate all the domain actions which are performed internally ?
For instance, suppose my domain is made of two entities : Article and Category. I can traverse an article to get its category, but I can't traverse a category to get its articles as it doesn't make sense in the context of my domain. Now, I have a business rule that states that whenever a category is disabled, all the articles on this category should be disabled as well.
The entry point for this action would be a disable($category) method on a CategoryFacade service. This action would first disable the category, then fetch all the articles of this category and disable them.
If I call the disable() action from a test case, I can validate that my category was correctly disabled as it is the actual object on which I am performing the test. But what about the articles ? I don't have a getArticles() method on my category, and since my domain only uses mocks as repositories, it wouldn't make any sense to fetch manually the articles and asserting on them.
Edit
The answer proposed below reminded me of something critical. Indeed, in my example, a category is to be considered as an AR as it has an existence outside the scope of an article. But since an article is an AR as well, it should be entirely responsible for its own consistency. That means that the deactivation of all articles linked to a category should not be initiated by a category service, as this service shouldn't know anything about articles. My choice will be the one proposed below : dispatch en event whenever a category is disabled, and perform deactivation on articles in a service which is inside the boundaries of my article.
In first place it is best to not test repositories togheter with domain logic and since repositories should be used only in application layer, then you shoudln't test application services. If you have to, then just create some test repository (memory based).
You should test your business rules just on domain objects. In example if you want to test if user rating works fine then do:
rated_user = UserFactory(parameters)
assertEqual(rated_user.rating, Rating(0))
rating_user = UserFactory(parameters)
rating_value = 3
rating_user.rateUser(rated_user, rating)
assertEqual(rated_user.rating, Rating(3))
Testing of your case is difficult because ARs should be changed in different transactions (probably even not in the same request). From what you say it seems that Category should be an AR (aggregate root), because in order to disable category we have to fetch one category without using an article to do so.
Now when you disable category, you should send event that articles should get and disable itself then. You can test if articles are disabled just by calling EventListener callback, that would be better IMHO. Testing both ARs togheter would be actually an integration test, which requires more setup.
Anyway, to test if all articles of a given category are disabled, you have to fetch them, probably using something like "articlesRepository.getArticlesOfCategory(category)" and check one by one if it's disabled. There is no other way.
We're investigating Alfresco for doing wideband delphi ("planning poker") based on submitted statements of work (collected user stories). I've been reading through the Alfresco documentation, and there are two questions that I haven't been able to get clear answers to:
Can we set it up so users can write, but not read, to a folder or node? (To support "anonymous" planning, without users knowing what the other users submitted estimates were)
Can workflow tasks be implemented to ask users to comment or submit items to a node or director with the above model, rather than just simple approve or deny?
Workflow:
User submits a statement of work
All users (or selected users at random, or ... ) in group get notice to review
Reviews include estimates on the overall SOW or specific phases
Reviews are anonymous/secret to all but the manager
Have you implemented something similar in Alfresco with fine grained access control? Sharing your experience would be very helpful... i'm not looking for someone to do the work for me, just to confirm it can be done.
I would use some kind of parallel workflow for this.
First the managers starts the workflow and the task type of this first node will have additional info about the user story and such, then the manager selects a people or a group to which it will send this user story.
Here comes the parallel thing into play. Because it's parallel noone sees the results of the other members of the workflow. The members fill in the requested fields (another custom task type with data like: score (estimate) and maybe explanation.
Before the workflow goes back to manager the automatic calculations are made in a non-user task/node where you calculate overall score for the story. You can include each individual user and their score in the result/report if necessary.
Now the results are sent to the manager.
I have a scenario as given in the below workflow diagram using core service.
First step is manual step author will create/edit content and finish the activity and it is assigned to everyone.
In the second step, I want to do filter the users based on their groups.
In the third step, couple of scenario
a. If the user belongs to group "A" I want to list out all the next 3 available activities, User A can choose any one of these 3 activities.
b. If the user belongs to group "B", I want to list out "Reviewer" and "Approver" activity as next activity, user b can select any one of these 2.
Can any one give some idea to achieve this?
You should turn your problem around. Yes, it is possible, but the amount of knowledge required will be a huge barrier for you to implement.
So, instead think about it differently.
Change your "Filter Next activity" automated activity to an automatic decision, and have your code that determines the group membership also determine which activity should be next
have 2 forward paths from there - 1 for the users of Group A, other for the users of group B
on each forward path, have different selection options. You may try having links to the same activity from 2 different manual decisions, I don't know if that works though.
Worst case scenario you'll have repeated activities (not in name, but in function), and you saved yourself about 2 months of headaches trying to cope with the learning curve of doing CME extensions.
The simple answer to your initial question is: "no, this functionality is not out of the box".
But of course many things are possible by implementing critical parts yourself.
You'd probably need a GUI extension of some sorts to allow the user to pick from a list.
You'd need to store the information between phases of your custom solution.
And you'd then need some code in an automated workflow activity to implement the picking of the next activity.
Most of these steps have been covered in other questions already. Did you have a look for each of these? If so, you might want to share how far you already got and where you are stuck.
I want to group visits by certain id number because every id represents a different client (think of a subdomain or something like that), for example:
http://site.com/234/home
http://site.com/234/search/something
are URL's for client 234, while...
http://site.com/155/home
http://site.com/155/search/something
are URL's for client 155.
I'm a total noob on this, thx!
Well one way permanent way to do this that that doesn't require you to change the tracking code in your markup is Advanced Segments.
Advantages of this technique in your case:
You can create each segment and given
them descriptive names (e.g., client
id);
Unlike, for instance, using an
Advanced Filter, the Advanced
Segments are active immediately (as
soon as you create them) and they
don't permanently alter your data.
Advanced Segments are simple to configure. This Post by the GA Team is an excellent step-by-step guide, or you can follow these two consecutive screen shots below:
Step 1: click Advanced Segments in the upper right-hand corner from the Dashboard view then click Create a new advanced segment when you see the view below:
There are a number of ways to configure your Advanced Segment; here i've chosen the Page Dimension from Content then selected Condition Contains then just key in a value for a path that distinguishes each client ID.
No exactly what you asked, but you can go to:
Content
Content Drilldown
See the aggregated unique pageviews and other info for each client /id/