Where does encodeAsSHA() function came from - grails

I'm starting out with Grails and I'm following the InfoQ ebook found here.
The book teaches about Authentication in Chapter 9 and how to encrypt the password. Below shows how it is done, but I don't understand how it works.
First, we need to create a class in grails-app/utils/SHACodec.groovy:
import java.security.MessageDigest
class SHACodec{
static encode = { target->
MessageDigest md = MessageDigest.getInstance('SHA')
md.update(target.getBytes('UTF-8'))
return new String(md.digest()).encodeAsBase64()
}
}
Then in my User domain, I need to add a closure to beforeInsert:
class User{
...
String password
def beforeInsert = {
password = password.encodeAsSHA()
password
}
...
}
The code is working fine, but I don't see the connection on how adding a class in grails-app/utils/SHACodec.groovy enable the use of the function encodeAsSHA() for password in the User domain.
Since the SHACodec class only assign a closure to encode, and never mention encodeAsSHA(). How is password(a String) able to use it out of no where?
I'm surely missing something here!

A Grails codec class is one that may contain an encode closure, a decode closure or both. When a Grails application starts up the Grails framework dynamically loads codecs from the grails-app/utils/ directory.
The framework looks under grails-app/utils/ for class names that end with the convention Codec. For example one of the standard codecs that ships with Grails is HTMLCodec.
If a codec contains an encode closure Grails will create a dynamic encode method and add that method to the Object class with a name representing the codec that defined the encode closure. For example, the HTMLCodec class defines an encode closure, so Grails attaches it with the name encodeAsHTML.

Related

How to access private fields without the 'part of' directive?

Set the case there are multiple libraries of a package which need access to a commonly used class which is in its own library. This class gets exported and contains private fields which should only be accessible internally by libraries of the package. Because the part of directive is discouraged I am avoiding it. So this is the challenge: How can I access private fields of a public class from another library of the same package without using part of?
This is what a came up with:
class PublicClass {
Object _shouldNotBePublic;
}
class InternalClass extends PublicClass {
Object get publicInternally => _shouldNotBePublic;
}
And it partially solves the problem.
But now there is an exported function
void someFunction(PublicClass param) {
param._shouldNotBePublic;
}
which takes an argument of PublicClass and it needs to access the private _shouldNotBePublic field. That is exactly what C++ friend does. Are there any good solutions for Dart that don't involve part of?
Edit: The workaround I use for the time being is a simple not exported function in the same library like PublicClass:
Object getShouldNotBePublic(PublicClass obj) {
return obj._shouldNotBePublic
}

Overriding default GORM id generator

In GORM, it is possible for someone to specify the default id generator in config.groovy by doing:
grails.gorm.default.mapping = {
id generator : 'uuid2', type: 'pg-uuid'
}
However, I have a class in a plugin which is expecting the id to be a long, so it falls over. I could change the plugin, but just wondering if I have any other options here?
Thanks
You could try implementing an AST Transformation on the domain classes of your project which would convert any Long fields to String fields.
Grails scans the package org.codehaus.groovy.grails.compiler for any classes which implement grails.compiler.ast.GrailsArtefactClassInjector. Create a class in this package which scans domain classes and removes any id properties which have a class of Long and replaces them with a property of class String (or whatever class type you need).

How out object work for custom tag library in grails?

In Grails i am using custom tag library, here is my code
def isCheck = { attrs, body ->
def checkUser = springSecurityService.currentUser
def owner = attrs?.owner
if(checkUser?.id == owner?.id) {
out << body()
}
}
But here how the out object work.I think its from TagLibraryApi class.But without any initialization how it's work.
can anyone give me the concept for using out object.
From the Grails docs:
there is an implicit out variable that refers to the output Writer which you can use to append content to the response
Think of it like a field from a super class that you are referencing.
In this context out refers to the output stream/writer. Typically this is going to be the GroovyPage from which it's called.
As far as using it, I'm not sure what you are looking for but your example is pretty complete. You can always browse the source code for the built in tags for Grails on Github.

Dart using Json_object to produce strong typing

Using the ideas outlined in ding the article Using Dart with JSON Web Services at https://www.dartlang.org/articles/json-web-service/, I have been trying to implement the section on using JsonObject and interfaces to produce a strong typing of JSON data.
The article indicates that one should write something like.
abstract class Language {
String language;
List targets;
Map website;
}
class LanguageImpl extends JsonObject implements Language {
LanguageImpl();
factory LanguageImpl.fromJsonString(string) {
return new JsonObject.fromJsonString(string, new LanguageImpl());
}
}
However the compiler 'fail' at the definition of the class LanguageImpl with the message
Missing inherited members: 'Language.website', 'Language.targets' and
'Language.language'
Even more confusing the code will run without a problem....
In Darteditor you get Quick fix support for this.
Set the caret at LanguageImpl and press ctrl+1 or use the context menu > Quick fix.
You get the missing concrete implementations you inherit from the abstract base class generated automatically.
Dart is a dynamic language and therefor very flexible.
The tools support you and try to give meaningful warnings and hints about what could go wrong
but don't prevent you running a program even when it is not yet finished.
You can use the #proxy annotation on the class to silent the warnings.
This also needs the class to have a noSuchMethod() implementation.

Is there any way to chain messages together in Grails' message.properties file?

In Grails there is a message.properties file. In this file message are defined like this:
exampleClass.fieldOne.label=Field One
otherExampleClass.fieldOne.label=Field One
I want the ability to use both messages even though they are textually the same. I would like to define them like this:
exampleClass.fieldOne.label=Field One
otherExampleClass.fieldOne.label=${message(code: 'exampleClass.fieldOne.label')}
... but that just make a a call to otherExampleClass.fieldOne.label return the string ${message(code: 'exampleClass.fieldOne.label')} instead of the desired string Field One.
In the message.properties I think that you cannot do it, but maybe with a convention and modifying the templates of the Grails you can achieve it. So my idea is:
Define a convention for your messages (for example, initialize the message with some special char)
exempleClass.fieldOne.label=FieldOne
otherExampleClass.fieldOne.label=#exempleClass.fieldOne.label
Create a TagLib to handle the message
class MyTagLib {
static namespace = "my"
def inheritedMessage = { attrs, body ->
String message = g.message(attrs)
if(message.startsWith("#")) {
//get the other message...
}
out << message
}
}
And finally install templates and change the <g:message/> for <my:inheritedMessage/> or whatever you call it.
For step 2, another approach is to override g.message(), with the benefit of not need the step 3 and make available for all parts of your app the modification. The con is that it will have to be good documented and disseminated or can cause some confusion in other devs.
EDIT
To cover all messages I think the better approach is to customize the messageResource used by Grails. Here is a question that covers how to do it with Spring, to get the messages from the database, could be a start point. And here is a question that shows how to replace the bean in Grails.

Resources