Adding Administrator user on application boot in Grails - grails

I am wondering how to add Administrator user to a Grails app on the boot.
Scenario: I developed Grails application and have User permission in place (implemented in Grails). Now once I deploy app on a server, the very first thing it should do is to create Admin user. My question is how to do it? I don't need elaborate "installation" right now.
My thoughts: I figured to put check and admin creation code in bootstrap, here is a sample code:
def admin = User.findByLogin("admin")
if (!admin) {
admin = new User(login:"admin", name:"Administrator", password:"password")
admin.save()
}
However everytime I run app in eclipse it fails to do anything. I mean no errors, no movement at all. Application runs fine but it seems like bootstrap is skipped completely.
Question is how do I add Admin user via Grails app on a first run or a boot?
If I need to use a bootstrap, what is an issue with my above code?

It's most likely the case that the save() call is failing to validate. Replace admin.save() with
if (!admin.save()) {
println "Failed to save admin due to errors: $admin.errors"
}
or something similar to get an indication of what's going on. Also add another println before this code to ensure that the code is even running - you may have a more significant error in the code.
In general it's best to run grails clean when code that should work doesn't. It forces a full recompilation and often makes weird behavior go away.

Try this code:
def admin = User.findByLogin("admin")
if (!admin) {
admin = new User(login:"admin", name:"Administrator", password:"password")
admin.save(failOnError:true)
}
The flag failOnError force grails to throw exception if save was unsuccessful due to validation errors, without this flag grails will not save instance silently.

Related

Grails - Won't open localhost when adding data to bootstrap.groovy

I am trying to learn Grails and following along the guide on grails.org http://guides.grails.org/creating-your-first-grails-app/guide/index.html which to some extend works fine. My issue is, that I follow the guide to the dot, and when I come to part 4.4 about bootstrapping data. I fill in the code in the BootStrap.groovy file in the init folder.
When I then proceed to run my app and try to connec to the url localhost:8080 the site simply will not load. I can acces the dbconsole and see that the data is bootstrapped, so I guess the app is working to some extend. But the site wont load.
When I remove 2 of the Vehicles, the site loads fine. I have tried using grails-clean, and kill all processes on the port 8080, stille nothing helps.
Please help me with this, as I am stuck!
In your save method call, add failOnError: true. It's likely that something is failing when you try to save it. Also keep an eye on your console for error messages.
If that doesn't help, post some exact code.

How can I setup the NuGet configuration to work under the IIS App Pool user account so I can download files from a custom NuGet source in ASP.NET MVC?

I am trying to download NuGet packages from a custom nuget server using an ASP.NET MVC website. The code I have runs fine under a console app, but when I run it under IIS I receive an exception:
System.InvalidOperationException: Package stream for 'MyPackage.1.0.0' cannot be found at 'https://mynugetserverurl'.
Each run under different credentials. My local user in the case of the console app and the standard IIS User (APP POOL\my.domain.name.com) in the other.
My custom nuget package source is setup for my local user and I have tried setting up the nuget.config for the IIS user in many different locations per this nuget documentation (https://docs.nuget.org/consume/nuget-config-file), but none appear to be recognized.
How can I setup the NuGet configuration to work under the IIS App Pool user account so I can download files from a custom NuGet source in ASP.NET MVC?
It turns out accessing nuget.config wasn't the issue after all. I found a version of the API where I could explicitly tell it which nuget.config file to use and verified that that user could access the file, but nothing changed. I confirmed that nuget was able to read the settings, but still the download wasn't working.
Tracing through the code I found out that DownloadToMachineCache (https://github.com/NuGet/NuGet.Client/blob/fb6430c6f8c79ec7a28fc2e64e80b89ccb9b1e8b/src/NuGet.Core/NuGet.Protocol.Core.v2/Resources/DownloadResourceV2.cs) was returning null. Code never reached line 301 because MachineCache.InvokeOnPackage was returning false. InvokeOnPackage calls a private method TryAct which reads as follows (https://github.com/ctaggart/nuget/blob/master/src/Core/Repositories/MachineCache.cs):
try
{
// Do stuff...
return action();
// Do more stuff...
}
catch (IOException ex)
{
}
catch (UnauthorizedAccessException ex)
{
}
return false;
Arghh - how frustrating.... It doesn't properly handle the issue at any level to let a user know what happened! Instead it swallows any useful information here and covers up what's really going on. I won't complain about swallowing an exception if you gracefully recover or tell me how to fix it, but if you don't then please just let me have the info so I can figure it out myself!
Anyway - action() calls back the delegate in InvokeOnPackage which tries to create a file at packagePath and write the downloaded .nupkg there - finally!
packagePath resolves to: C:\Windows\System32\config\systemprofile\AppData\Local\NuGet\Cache
Besides access to nuget.config, you also need write access to this path in order for NuGet to function under an IIS User. Hopefully I can find another NuGet API that will allow me to tell it to use a more appropriate path for it's on-disk cache!
Note: In my research I also came across this: https://github.com/NuGet/Home/issues/2140
Maybe they'll be good enough to break me in upcoming release! I am currently using v3.3.
Hope someone finds this helpful.

How to deploy client-side service WSDLs

I have code using the SysOperationFrameworkService, and after a model-deploy or some other set of circumstances, many users get Function SysOperationDataContractInfo::newParameterInfo has been incorrectly called..
It's unable to be resolved with full-compile, sync, full CIL, deleting XPPIL files, deleting AUC/KTI, usage data, security (they're admin), refreshing caches (server &client), etc. and I have a ticket open with Microsoft and they're struggling.
I've narrowed the issue down to when the service group AxClient located in the AOT at \Service Groups\AxClient WSDL files get deployed to C:\Users\[User]\AppData\Local. Either those files existing there, or something happening when those files get deployed is needed.
Any idea how/what causes these files (AxClient.wsdl, etc) to be created? With a user who happens to be "working", I can close the client, delete all the files, open the client, and no files will exist...then I perform a SysOp process and those files get created during that process. With the non-working user, with same security on the same machine does it, the files don't get created.
I have found that the
"Function SysOperationDataContractInfo::newParameterInfo has been incorrectly called" has been throwed because of a possible bug in the kernel when calling the "dictMethod = new DictMethod(UtilElementType::ClassInstanceMethod, dictClass.id(), methodName);" in the SysOperationServiceController.getServiceOperation() method. In my case the new DictMethod was sometimes unable to get the method parameter from a superclass, causing the _parentMethodParameterName check fail in the SysOperationDataContractInfo.newParameterInfo.
So, I solved the issue just by doing an override of the super method where the parameter could not be retrieved and then just calling super(_parameter), then everything went well.
Have you tried axclicfg.exe -> connections -> refresh

Grails withForm and AWS interactions

The following issue is using the following:
AWS
PostgreSQL
Grails 2.3.3
Redis
On our account creation page, we are having some REALLY obscure functionality with the Grails withForm{}.invalidToken{} closure.
Upon hitting the page for the first time, everything works fine. You can post back to the server fine as long as you do not leave this page.
Upon leaving this page, either through navigation links or logging off, returning to the page (Again through navigation links or logging on and heading there), we can no longer submit, it hits the invalidToken closure every time.
I know AWS is involved as we took the project and deployed it to local machines both with IntelliJ and Tomcat by itself and both work fine. This issue only occurs upon deploying the WAR to AWS. (This occurs both with local builds and automated builds. They work locally but not on AWS)
We have spent almost a week on this issue trying to figure out why this is occuring, and all we have to show for it is we know AWS is somehow involved, but that's as far as we have gotten.
Does anyone have any insight into what would be causing our session to act like this?
After a LOT of searching about this issue, me and my team finally figured it out. Taken directly from our JIRA:
"This issue is caused by the implementation of tomcat-redis-session-manager used on AWS. As per their documentation (https://github.com/jcoleman/tomcat-redis-session-manager#session-change-tracking), there are "unintended consequence of hiding writes if you implicitly change a key in the session or if the object's equality does not change even though the key is updated." Specifically, the "useToken" implementation is Grails 2.3.8 is: "String generateToken(String url) { final UUID uuid = UUID.randomUUID() getTokens(url).add(uuid) return uuid }" The combination of these native implementations are there for incompatible.
The tomcat-redis-session-manager does support a manual dirty tracking mode by setting: RedisSession.setManualDirtyTrackingSupportEnabled(true); but this would require a forked build of SynchronizerTokensHolder in grails-core."

Grails/Spring Security: Unable to login with a newly created user

I have just started using grails and installed the spring-security and spring-security-ui plugins. I am following the tutorial given here. The application starts with one bootstrapped user me with ROLE_ADMIN permission.
With the UI override scripts I was able to get the register functionality up and running and it works all right. Now, I have installed the User Management scripts (grails s2ui-override user) to try adding, editing, removing users.
A new user gets created fine, I have checked this against the HSQLDB instance. However, if I now log-out from the application and try to login with the newly created user the application tells me that it is unable to find a user with the provided username and password.
I haven't modified the default logout handling so am using /j_spring_security_logout which as the documentation says invalidates the session.
Is this a know issue? If so how can I get around this or if not how can I debug this issue?
EDIT:
This issue is also persisting without the UI addition. Register as a new user. Once you finish e-mail verification you are auto-logged in to the site. Now logout and try to login in back again. It gives the same error.
FINAL EDIT:
The UI plugin comes with the RegisterController that still encodes the password. However, the newer domain classes that come with the core are also doing this and the recommended practice is that controllers shouldn't. I commented out a line that does the encoding and the login/logout works now at least for the basic scenario.
There is a warning on that tutorial
Earlier versions of the plugin didn't include password encryption logic in the domain class, but it makes the code a lot cleaner.
I am guessing security-ui plugin does not know about that change, and comparing unencrypted password with the encrypted one on the database.
l managed to fix my problem. The problem was double encryption. Under the spring security ui in the user controller on line 41 the password was being encrypted and then again by the domain class so on login it was comparing a double encrypted password and a single encrypted password. To solve the problem l just commented out line 41 in the user controller which was encrypting the password
EDIT: If you have trouble figuring out where one would go to edit the controller, you can find the source code of the downloaded plugins in your user home's
/.grails/version/projects/projectname/plugins
directory for editing (at least on Mac / Linux, dunno where you'd find it in windows).

Resources