I am using simple membership provider and mvc. After a user registers he/she will be redirected to a view called registerDepartments. Incase time is an issue the user can login at a later stage. How do I retrieve the data registered by the user previously. In my previous workings it shows all the data from the table for all users who registered a branch.
I didn't get your question clearly, because you didn't show any code of your work and any example.
However I think you want to retrieve branches created by a user for him/her right? If So, you can use something like the following:
var currentUserId = (int)Membership.GetUser().ProviderUserKey;
var branches = dbCtx.Branches
.Where(b => b.CreatorUserId == currentUserId).ToList();
Related
While developing a multi-tenant app with ASP.NET Core I noticed that it brings 2 new indices: NormalizedUserName & NormalizedEmail.
The main problem is that it gets too difficult to have a unique user per tenant.
What I mean is having multiple users with the same UserName & Email but different TenantID.
In order to achieve this I have to remove those indices
public static void RemoveIndexes(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>(entity =>
{
var normalizedUserNameIndex = entity.HasIndex(u => new { u.NormalizedUserName }).Metadata;
entity.Metadata.RemoveIndex(normalizedUserNameIndex.Properties);
var normalizedEmailIndex = entity.HasIndex(u => new { u.NormalizedEmail }).Metadata;
entity.Metadata.RemoveIndex(normalizedEmailIndex.Properties);
});
}
My questions are:
What is the purpose of these 2 new indices?
What would it affect if we just remove them?
Is there anything we need to pay close attention to after removing them? (e.g. overriding default UserManager functionality or something to that effect)
First of all, I wouldn't change anything of the Identity Framework if I can't oversee the effects. If you insist, you can test what happens yourself. But, do you need to remove the fields?
If the relation of user-to-tenant is one-to-many, then tenantId should not be a field of ApplicationUser but rather be stored in a seperate table, like UserClaims.
You can add multiple tenantId's as claim of the same type, like http://tenant.company.com/Id. It will then become a collection of values, like what happens with roles.
If you don't want this then you can use different claimtypes, like http://tenant.company1.com/Id, http://tenant.company2.com/Id or something like that.
You can choose to include only claims that are linked to the tenant, which could be determined from the site binding or the url, for instance.
This design allows the user to login using the same password everywhere. Please note, this is about identity: who is the user? The user doesn't need to have a different password for every tenant.
It also makes it easier to change a password. Because I wonder, how does your scenario look like with multiple user records for each tenant? Will you update all records at once when a password changes? And how will you support 'forgot password' and other features?
I have an event object with Payments collection. When event is cancelled I need to add those payments to the appropriate User object Refunds collection. Based on the documentation I came to the following schematic script:
_(this.Payments).forEach(function(payment) {
var user = LoadDocument(payment.UserId);
user.Refunds.push(new { EventId = this.Id, Payment = payment });
}
There are two things in this schematic script that I didn't find how to do right in the documentation:
1. Load another document by Id (line 2)
2. Create new json-object (line 3)
The LoadDocument() is correct, however the loaded document isn't automatically tracked by any Unit of Work when loaded within a Patch.
You have to tell Raven to update/store that document as well:
var user = LoadDocument(payment.UserId);
user.Refunds.push({ EventId = this.Id, Payment = payment });
PutDocument(user.UserId, user);
If you really want to do this from a patch, the above might work. However, this seems like a more domain specific operation and might be better to model the behaviour in your application code (i.e. raise an event and add the refunds to the user objects from code). Not 100% sure how Raven handles transactions within patches and so on...
Edit: For your second question: You don't need to use the 'new' keyword
We are having a portlet on a liferay page. We want to put up up a permission on every action method that is performed. For example on page A we have landed an XYZ portlet. Now we want that whenever there is any action performed form this portlet, we want to check that if the user is having a role to perform this action or not.
It wont be a good approach to put up the code in Action method of the portlet cause we are having approximately 20 such pages and portlets.
Can we have some sort of filter or so, so that each action request is checked if the user is having the access to the content or not.
Thank you...
My idea.
Use a filter to intercept all request
You can add a filter to the Liferay Servlet to check every request.
For that you can use a hook-plugin.
Look at this :
http://www.liferay.com/fr/documentation/liferay-portal/6.1/development/-/ai/other-hooks
http://connect-sam.com/2012/06/creating-servlet-filter-hook-in-liferay-6-1-to-restrict-access-based-on-ip-location/
Issue with filter is that you can't access ThemeDisplay or use PortalUtil.getUser(request).
So you must use work around like that :
private User _getUser(HttpServletRequest request) throws Exception {
HttpSession session = request.getSession();
User user = PortalUtil.getUser(request);
if (user != null) {
return user;
}
String userIdString = (String) session.getAttribute("j_username");
String password = (String) session.getAttribute("j_password");
if ((userIdString != null) && (password != null)) {
long userId = GetterUtil.getLong(userIdString);
user = UserLocalServiceUtil.getUser(userId);
}
return user;
}
Filtering the request
To filter the request you must get :
page id (Layout id in Liferay)
portlet id
portlet lifecycle
One more time using a filter is a pain because you can get the ThemeDisplay. These params are easy to get (with real object instancee) with ThemeDisplay.
So you must get this as parameter in the request.
final String portletId = ParamUtil.get((HttpServletRequest) servletRequest, "p_p_id", "");
final String layoutId = ParamUtil.get((HttpServletRequest) servletRequest, "plid", "");
final String portletLifecycle = ParamUtil.get((HttpServletRequest) servletRequest, "p_p_lifecycle", "");
Lifecycle details :
portletLifecycle is a int and the meaning of value is :
0 : RENDER
1 : ACTION (the one that interests you)
2 : RESOURCE
I think that with this data you can be able to define if user can or cannot make the action.
You can get user roles from the user.
You can get the current page and portlet linked to the request.
And you can know if the request is an action request.
Good luck with Liferay.
You can add freely configurable permissions to Liferay, see the Developer Guide for detailed information. My first guess on this would be that these affect "model resources", e.g. the data that your portlet is dealing with, rather than portlet-resources, e.g. permissions on the individual portlet itself. Think of portlet-permissions as permissions that are defined by Liferay, model-resources as permissions where you can come up with your own vocabulary on the actions, e.g. "UPDATE_ADDRESS" etc.
These permissions will typically be tied to roles, which are granted to users/usergroups/etc.
Based on this variability, it depends on the nature of your permissions if you can write a filter to generically check permissions, or if it depends on more than the individual action call.
If you determine that there is a generic solution, look up PortletFilters, they behave just like ServletFilters. These can easily provide a home for permission checks.
It's quite hard to cover this topic in such a short answer, I hope to have given enough resources for you to continue your quest.
You can abuse some existing portlet permission like "Add to Page" and set it to roles that should call the action.
And by the rendering and action phases validate "has the user necessary permission".
Or you can create new permission and configure it by portlet-configuration. This way is cleaner, but difficulty.
My Users table (the one that I created) has the following columns:
UserId,UserName,FirstName,LastName,DOB
After I ran this command
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "Users", "UserId", "UserName", autoCreateTables: true);
it created the required simple membership tables for me.
How would I go about "UnConfirming" an user or setting the "IsConfirmed" flag to false in the webpages_Membership using the new SimpleMembership API?
(Earlier, before going to simplemembership using the "Membership" class I could update an user using the api call : Membership.UpdateUser( user );)
I can't answer your question directly since I couldn't figure out a way to 'unconfirm' an account either. What I ended up doing, however, may help whoever finds this question.
I basically use Roles as a gatekeeper. Whenever I create a new account I add that user to a "User" role:
Roles.AddUserToRole(newUser.Username, "User");
I use the Authorize attribute to restrict access to my controllers (and use [AllowAnonymous] for actions that I want to be public -- like RegisterUser, for example). Then, inside each action I add a method to restrict access to only users that are in the "User" role.
if (!Roles.IsUserInRole(role))
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.Unauthorized));
}
NOTE: I'm using Web API, but if you're using MVC you should have a much easier time. Instead of manually checking if a user is in a role in each action you can just use the authorize attribute:
[Authorize(Roles = "User")]
When I want to "UnConfirm" a user I just remove them from the "User" role.
Roles.RemoveUserFromRole(user.Username, "User");
This way if a user comes crawling back I can just reactivate their account by adding them back as a User.
What I ended up doing was updating that table directly via a SQL query. Not sure if thats the recommended way of doing it, but that seemed to work for me.
(Thanks for your suggestion too).
Look at this blog post on adding email confirmation to SimpleMembership registration process, which covers how the confirmation process works. The cliff notes are that when you create a new user you set the flag that you want to use confirmation like this.
string confirmationToken =
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email }, true);
When you do this the CreateUserAndAccount method returns a unique token that you can put in an email with a link so the user can confirm that they gave you a valid email address. When they click on the link it passes the token in the URL and the controller action can then confirm the token like this.
[AllowAnonymous]
public ActionResult RegisterConfirmation(string Id)
{
if (WebSecurity.ConfirmAccount(Id))
{
return RedirectToAction("ConfirmationSuccess");
}
return RedirectToAction("ConfirmationFailure");
}
The ConfirmAccount method checks if there is an uncomfirmed token that matches in the database and if there is it sets the isConfirmed flag to true. The user will not be able to logon until this is set to true.
set requireConfirmationToken to be true: (The 4th value shown below)
WebSecurity.CreateUserAndAccount(viewModel.UserName, viewModel.Password, null, true);
Source
http://www.w3schools.com/aspnet/met_websecurity_createuserandaccount.asp
how can I get all accounts of am employee?
In the "Siebel Object Interaces Reference" I found an example, how to get all industries of an account:
var myAccountBO = TheApplication().GetBusObject("Account");
var myAccountBC = myAccountBO.GetBusComp("Account");
var myAssocBC = myAccountBC.GetMVGBusComp("Industry");
So I would like to do something like:
var myEmployeeBO = TheApplication().GetBusObject("Employee");
var myEmployeeBC = myAccountBO.GetBusComp("Employee");
var myAssocBC = myAccountBC.GetMVGBusComp("Account");
But I get an error
Semantic Warning around line 23:No such predefined property Account in class BusComp[Employee].MVGFields.
I can see in Tools that there is no Multi Value Link called "Account" in Business Component "Employee", so I can actually understand the error message.
So I wonder how I can get all accounts of an employee.
I found the Business Component "User" which has a Multi Value Link to "Organisation" and another link "User/Account".
Is this what I am looking for?
How can I know? Where is documentation which tells me about the semantics of links? (Is this described in "Siebel data model reference"? I cannot download this document, although I have signed in...) This link could also link a user to the organization it belongs to.
If one of these links IS what I am looking for, what would be the way to go to get the "User" Business Component of a corresponding "Employee" Business Component?
Many questions of a Siebel newb...Thanks for your patience.
Nang. An easy way to approach this (and to learn it) is to figure out how you'd do it in the UI. Then move onto figuring out how to do the same thing in script.
When you say, "get all account of an employee," do you really mean get all accounts where a particular employee is on the account team? In the UI, that would be done by going to: Accounts > All Accounts Across Organizations, and querying for that specific user in the "Account Team" multi-value field.
From that same view, go to Help > About View in the application menu. You'll see in the popup that the view uses the Account business object and the Account business component. A quick examination of the applet you queried on will show you that the "Account Team" field on the applet is really the "Sales Rep" field on the Account business component. Here's how to mimic what we did in the UI, in script:
var boAccount = TheApplication().GetBusObject("Account");
var bcAccount = boAccount.GetBusComp("Account");
bcAccount.SetViewMode(AllView); // like All .. Across Orgs
bcAccount.ClearToQuery();
bcAccount.SetSearchSpec("Sales Rep", "NANG");
bcAccount.ExecuteQuery();
Then you can walk through the list of accounts and do something with each one like this:
// for each account
for (var bIsRowActive = bcAccount.FirstRecord();
bIsRowActive; b = bcAccount.NextRecord())
{
// do something here
}
I hope you're enjoying Siebel.