This a example of grails that I'm learning,
I have two Domains, and whenever I call the controller, it gives me an error that I gave him a int but needed a package.domain.
User and other is Test. which contain:
Test Domain:
Long id
Date created
bool enabled
User user
User Domain:
Long id
String firstname
String lastname
And my controller:
user.id = 1
def test = new Test(
created: new Date(),
enabled: true,
user: id));
... test.save(flush:true)
I don't know how to get the User domain using their attributes in my Test Domain. Can someone explain.
The Test constructor expects a domain object for the value for user property. So maybe try something like this (replacing 1 as appropriate):
def test = new Test(created: new Date(), enabled: true, user: User.get(1));
Related
I am trying to add new field to the user profile (student number) and allow users to login using either email or the new field (student number) with the same password for both.
I have overridden login.jsp to allow both Email and Student Number.
My idea is to override the login action command with something similar to the code below:
#Component(
property = {
"javax.portlet.name=com_liferay_login_web_portlet_LoginPortlet",
"mvc.command.name=/login/login"
},
service = MVCActionCommand.class
)
public class CustomLoginActionCommand extends BaseMVCActionCommand {
#Override
protected void doProcessAction(ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
HttpServletRequest request = PortalUtil.getOriginalServletRequest(
PortalUtil.getHttpServletRequest(actionRequest));
HttpServletResponse response = PortalUtil.getHttpServletResponse(
actionResponse);
String login = ParamUtil.getString(actionRequest, "login");
String password = actionRequest.getParameter("password");
boolean rememberMe = ParamUtil.getBoolean(actionRequest, "rememberMe");
String authType = CompanyConstants.AUTH_TYPE_EA;
String email = "";
if(isValidEmail(login)){ //if the user trying to login with his email
email = login ;
}
else if(isNumeric(login)){ //check if the user trying to login with his student number
//fetch User by Student Number (login)
//e.g. fetchUserByStudentNumber(login)
//get the Email Adress for the retrieved user object and use it to login
email = user.getEmailAddress();
}
else{
// Exception
}
AuthenticatedSessionManagerUtil.login(request, response, email, password, rememberMe, authType);
actionResponse.sendRedirect(themeDisplay.getPathMain());
}
}
is this the right way to achive similar requierment?
in Liferay 7.4 U46+, we can extend supported system services with Liferay Objects. so I have two options to extend the User Profile, 1- by adding a new field to the User object. or 2- by creating a new "custom field". which option is better?
in both options, how to force unique values in the added field (student number)?
how to retrieve user object by using added field (fetchUserByStudentNumber)?
Appreciate your feedback!
Thanks
Overwriting the portal login command is possible, but I would rather use a custom Authenticator to not overwrite other logic implemented in the MVC action component. As you want booth (mail and student number), you could implement authenticateByEmailAddress like in Password-Based-Authentication-Pipelines and check both authentication results with a boolean OR approach.
Extending portal model objects should rather be implemented via Custom Fields. Fetching a user like in fetchUserByStudentNumber you will probably need the ExpandoValue service and a dynamic query. Maybe there are better approached, but this is what comes into my mind first.
I am using Laravel 5.1 and Laravel's default authentication system.
In database (MySQL) I add a new column named 'role'. The value will be 1 for admin and 2 for members.
Now I want to give login permission only for admin, means where the value is 1. How can I do that?
Actually I solved it. I just add these code in postLogin() method of AthenticatesUsers.php method.
// If role is equal to 1, user allowed to login
// You can change $admin value anytime according to database Design
// Example: In role column the value for admin is 2 or A. You just need to change the value of $admin.
$userData = User::select('role')->where('email',$request['email'])->first();
$admin = 1;
$role = $userData->role;
if($role == $admin){
$request['role'] = $role;
}
I feel that there are better ways to achieve what you're after, such as middleware, however given what you're after this would be one way to do it.
Upon logging in a user us sent to 'home', unless you specify otherwise in the AuthController.
Inside your routes.php, if you just set up a GET route to point to a HomeController (or whatever you name it) then you could use a function to run the tests you're after.
routes.php
Route::get('home', 'HomeController#index');
HomeController
public function index()
{
//If they are yet to log in then return your normal homepage
if (Auth::guest())
{
return View::make('home');
}
else
{
//Run your tests here to check their role and direct appropriately
//Given you have added the role column to the users table, you can access it like so:
//Auth::user()->role
}
}
I'm working on GGTS 3.4 - Whilst creating an new instance of the domain model VideoDisplayMgmtShr I have introduced query check on the content of a domain model of an h2 dB prior to creating a new instance of that domain. Here is the query:
def vidDispMgmLst = VideoDisplayMgmtShr.findAll{ displayMode == videoDisplayMgmtShrInstance.displayMode}
The error is:
Class: org.h2.jdbc.JdbcSQLException
Message: NULL not allowed for column "EXPIRY_DATE";
SQL statement: insert into video_display_mgmt_shr ...
If I remove this check query the save of the new instance works fine - as the expiryDate is not null. I am doubly confused as the query is not creating a new instance so I don't see why it should throw this error? Also the expiryDate is set of null allowable in the model definition.
One last thing this domain model has a belongsTo constraint with another domain model - but that is all being taken care of in the create.
The domain class is:
class VideoDisplayMgmtShr {
// Defines the management of all videos that are published
static constraints = {
description(blank:true, nullable:true)
startDate(blank:true, nullable:true)
expiryDate(blank:true, nullable:true)
pubRights(inList:["Full", "Rest"]) // Full - full publish rights
//Rest- Restricted rights - with a watermark for some concessionary publishing
displayMode(inList:["Vanilla", "Vimeo", "YouTube"])
}
static mapping = {
datasource 'publish'
}
String description
Date startDate = new Date()
Date expiryDate = new Date() + 100
String pubRights = "Rest" // display type
String displayMode = "Vanilla" // type/ destination of publication
static belongsTo = [ publishedBT: PublishedShr]
}
With this domain class belongTo' another domain class:
static hasMany = [vidDMHM: VideoDisplayMgmtShr] // links to a display management entry
Not Sure is this is relevant but this has another mapping condiution:L
static mapping = {
datasource 'publish'
vidDMHM cascade: "all-delete-orphan"
}
Has anyone seen anything like this before?
-mike
I have my routes setup like this to allow action-based routing for my webapi controllers:
config.Routes.MapHttpRoute("DefaultApiWithIdAndAction", "{controller}/{id}/{action}", null, new { id = #"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithId", "{controller}/{id}", null, new {id = #"\d+"});
config.Routes.MapHttpRoute("DefaultApiWithAction", "{controller}/{action}");
config.Routes.MapHttpRoute("DefaultApiGet", "{controller}", new { action = "Get" },
new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
config.Routes.MapHttpRoute("DefaultApiPost", "{controller}", new {action = "Post"},
new {httpMethod = new HttpMethodConstraint(HttpMethod.Post)});
Here are all of the types of routes I want to support. They all work except for the default PUT without an action. Action based PUT requests work just fine for some reason.
GET users
GET users/1
POST users
PUT users/1 <- thinks its a duplicate route
PUT users/1/assignrole <- of this route even though this one works
DEL users/1
Here is how I defined my controller actions:
public UserModel Put(int id, UserModel model)
[ActionName("assignrole")]
public UserModel PutAssignRole(int id, RoleModel model)
I would have thought that they are different due to the action name being different but mvc is not seeing it that way. What am I doing wrong?
You need to differentiate the signatures of the two methods. Change your first route to:
config.Routes.MapHttpRoute("DefaultApiWithIdAndAction",
"{controller}/{id2}/{action}",
null,
new { id2 = #"\d+" });
and then change your second action to:
[ActionName("assignrole")]
public UserModel PutAssignRole(int id2, RoleModel model)
{
...
}
Just to give you all an update, I have abandoned trying to do this with traditional webapi routing. I have adopted attribute-based routing using attributerouting.net since it appears to be the solution most are pushing to solve this issue. I made my decision mostly since the attributerouting.net functionality is being rolled into WebAPI 2 for VS2013 release. The syntax is slightly different but the features are almost exactly the same. Its a huge improvement. Even stackoverflow uses it for their routes, which helped solidify my decision even more.
You could try and restrict the first routing definition to accept just this one action since it doesn't seem to be used for any other route anyway:
config.Routes.MapHttpRoute("DefaultApiWithIdAndAction",
"{controller}/{id}/{action}",
null,
new { id = #"\d+", action="assignrole" });
I have an intranet server on a Windows domain (server is Windows 2003, IIS6, NTFS permissions). It is on the domain Domain01. I have users from two domains in the same forest that access this intranet: Domain01 and Domain02 (DCs also running Windows 2003). Currently, the users are required to login by entering either:
Domain01\username or username#Domain01
My users are completely and thoroughly confused by having to enter the domain each time they log in.
Is there any way to simply allow them to log in by entering just their username and password WITHOUT the domain? For example, have the server try Domain01 by default, and if the login fails to try Domain02?
NOTE: I would like to do this via IIS or server settings if possible, rather than programmatically (for reference, I am using ASP.NET 2.0).
Yes. Usually what I do is do a global catalog search using the supplied user name as the sAMAccountName. Doing this with a PrincipalSearcher requires getting the underlying DirectorySearcher and replacing it's SearchRoot. Once I find the corresponding user object I extract the domain from the user object's path and use that as the domain for the authentication step. How you do the authentication varies depending on what you need it to do. If you don't need impersonation you can use PrincipalContext.ValidateCredentials to make sure that the username/password match using a PrincipalContext that matches the domain of the user account that you previously found. If you need impersonation check out this reference.
// NOTE: implement IDisposable and dispose of this if not null when done.
private DirectoryEntry userSearchRoot = null;
private UserPrincipal FindUserInGlobalContext( string userName )
{
using (PrincipalSearcher userSearcher = new PrincipalSearcher())
{
using (PrincipalContext context
= new PrincipalContext( ContextType.Domain ))
{
userSearcher.QueryFilter = new UserPrincipal( context );
DirectorySearcher searcher
= (DirectorySearcher)userSearcher.GetUnderlyingSearcher();
// I usually set the GC path from the existing search root
// by doing some string manipulation based on our domain
// Your code would be different.
string GCPath = ...set GC path..
// lazy loading of the search root entry.
if (userSearchRoot == null)
{
userSearchRoot = new DirectoryEntry( GCPath );
}
searcher.SearchRoot = userSearchRoot;
using (PrincipalContext gcContext =
new PrincipalContext( ContextType.Domain,
null,
GCPath.Replace("GC://",""))
{
UserPrincipal userFilter = new UserPrincipal( gcContext );
userFilter.SamAccountName = userName;
userSearcher.QueryFilter = userFilter;
return userSearcher.FindOne() as UserPrincipal;
}
}
}
}