grails loginfilter blocks css - grails

I've some troubles with my loginfilter in grails. If there is no session, it redirects me to the login page, but it blocks the css.
class LoginFilters {
def filters = {
loginCheck(controller: '*', action: '*') {
before = {
println("USER: "+session.user)
println("ActionName: "+actionName)
println("Controller: "+controllerName)
if (session.user == null) {
println("Redirecting to Loginpage")
render(view: '/index');
return true
}else{
return true
}
}
}
}
}
Where is my problem?

Related

MVC5 routing Programming C#

public static CustomerInfo Customer
{
get
{
if (System.Web.HttpContext.Current.Session["CustomerData"] == null)
{
System.Web.HttpContext.Current.Response.Redirect("~/Account/Login");
return new CustomerInfo();
}
else
{
return (CustomerInfo)System.Web.HttpContext.Current.Session["CustomerData"];
}
}
set
{
System.Web.HttpContext.Current.Session["CustomerData"] = value;
}
}
Whenever HttpContext.Current.Session["CustomerData"] is null, instead of redirecting to Login view in Account controller it is giving exception.
You can use
Return RedirectToAction("Login", "Account");
to redirect to another controller and method
Try:
if (System.Web.HttpContext.Current.Session["CustomerData"] == null)
{
Session["CustomerLogin"] = "True";
return new CustomerInfo();
}
else
{
Session["CustomerLogin"] = "False";
return (CustomerInfo)System.Web.HttpContext.Current.Session["CustomerData"];
}
Then in your controller check:
if(Convert.ToString(Session["CustomerLogin"]) == "True"){
return RedirectToAction("Login", "Account");
}

How to use Controller.TryUpdateModel outside of the Controller context?

is it possible to use Controller.TryUpdateModeloutside of the Controller context?
For Example suppose that I want to use Controller.TryUpdateModel method in class which does not belong to MyApp.Controllers so how that could be done?.
this is my code.
public ActionResult ValidateAndSignUp(company newCompany)
{
if (ModelState.IsValid)
{
newCompany.CDTO.File = Request.Files["Logo"];
if(new CompanyActions().AddCompany(newCompany))
{
ViewBag.message = newCompany.CDTO.Message;
return View(newCompany.CDTO.RedirectTo);
}
else
{
if (newCompany.CDTO.HasFileError)
{
ModelState.AddModelError("Logo", "Invalid File");
return View(newCompany.CDTO.RedirectTo, newCompany);
}
else
{
ViewBag.error = newCompany.CDTO.Error;
return View(newCompany.CDTO.RedirectTo);
}
}
}
else
{
newCompany.CDTO.Countries = new DropDownLists().GetAllCountries();
return View("signUp", newCompany);
}
}

Grails controller's beforeInterceptor

I am trying to make it so that no matter what function of my controller is accessed, if the session has been nulled, it goes back to the log in page after you click ok on a modal that pops up saying the session has expired but I can't quite get it to work. Here are the first few methods of this controller:
def beforeInterceptor = {
[action:this.&checkSession()]
}
def checkSession() {
if (!session.user) {
render text: """<script type="text/javascript"> alert('Session expired. Please log in again.'); window.location.href = data.url;</script>""",
contentType: 'js'
}
}
def index() {
redirect (action: customerLogin)
}
def customerLogin = {
selectedBatch = null
}
def authenticate = {
def user = null
def possibleUsersList = User.findAllWhere(user_name: params.username)
possibleUsersList.each {
if (bcryptService.checkPassword(params.password, it.user_password))
user = it
}
if (user) {
session.user = user
greetingName = user.user_name
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'customer', action: 'custMainPage')]
}
}
else {
//def messages = ResourceBundle.getBundle('messages')
//def errorstring = bundle.getString("fatcaone.login.error")
//println "Login error: " + ${errorstring}
render (contentType: 'text/json') {
//["message": '<p>code=fatcaone.login.error</p>']
["message": '<p>Login or Password incorrect.</p>']
}
}
}
def logout = {
if (session.user != null) {
flash.message = "Goodbye ${session.user.fullName}"
session.user = null
}
redirect(action: customerLogin)
}
beforeInterceptor has been removed from Grails 3.0.
See https://github.com/grails/grails-core/issues/635 for a discussion of this.
Given that you want to keep your code as it is do:
def beforeInterceptor = {
[action:this.&checkSession()]
}
private def checkSession() {
if (!session.user) {
flash.error = 'Session expired. Please log in again.'
redirect(action: customerLogin)
return false
}
}
def index() {
redirect (action: customerLogin)
}
def customerLogin = {
selectedBatch = null
}
def authenticate = {
def user = null
def possibleUsersList = User.findAllWhere(user_name: params.username)
possibleUsersList.each {
if (bcryptService.checkPassword(params.password, it.user_password))
user = it
}
if (user) {
session.user = user
greetingName = user.user_name
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'customer', action: 'custMainPage')]
}
}
else {
//def messages = ResourceBundle.getBundle('messages')
//def errorstring = bundle.getString("fatcaone.login.error")
//println "Login error: " + ${errorstring}
render (contentType: 'text/json') {
//["message": '<p>code=fatcaone.login.error</p>']
["message": '<p>Login or Password incorrect.</p>']
}
}
}
def logout = {
if (session.user != null) {
flash.message = "Goodbye ${session.user.fullName}"
session.user = null
}
redirect(action: customerLogin)
}
And in your login page add:
<g:if test="${flash.error}">
<script type="text/javascript">
alert('${flash.error}');
</script>
</g:if>
Check this
def checkSession() {
if (session == null || session["loginId"] == null) {
render text: """<script type="text/javascript"> alert('Session expired. Please log in again.'); window.location.href = "${createLink(controller: 'test',action: 'logout')}";</script>""",
contentType: 'js';
return false;
}
}

idiom for save and update methods in grails

Are there in any idioms in grails which help us with saving domain objects ?
For example
i may want to do something like
if(candidate.hasErrors || !candidate.save)
{
candidate.errors.each {
log it
}
However i do not want to spread the logic across all the places i do domainObject.save.
I also do not want seperate class like say repo to which I pass this domainObject and put in this logic
Thanks
Sudarshan
Here's a service method that I've used to validate and save, but log resolved validation messages on failure. It's helpful to use this instead of just println error or log.warn error since the toString() for error objects is very verbose and you just want to see what would be displayed on the GSP:
class MyService {
def messageSource
def saveOrUpdate(bean, flush = false) {
return validate(bean) ? bean.save(flush: flush) : null
}
boolean validate(bean) {
bean.validate()
if (bean.hasErrors()) {
if (log.isEnabledFor(Level.WARN)) {
def message = new StringBuilder(
"problem ${bean.id ? 'updating' : 'creating'} ${bean.getClass().simpleName}: $bean")
def locale = Locale.getDefault()
for (fieldErrors in bean.errors) {
for (error in fieldErrors.allErrors) {
message.append("\n\t")
message.append(messageSource.getMessage(error, locale))
}
}
log.warn message
}
bean.discard()
return false
}
return true
}
And here's an example in a controller:
class MyController {
def myService
def actionName = {
def thing = new Thing(params)
if (myService.saveOrUpdate(thing)) {
redirect action: 'show', id: thing.id
}
else {
render view: 'create', model: [thing: thing]
}
}
}
Edit: It's also possible to add these methods to the MetaClass, e.g. in BootStrap.groovy:
class BootStrap {
def grailsApplication
def messageSource
def init = { servletContext ->
for (dc in grailsApplication.domainClasses) {
dc.metaClass.saveOrUpdate = { boolean flush = false ->
validateWithWarnings() ? delegate.save(flush: flush) : null
}
dc.metaClass.validateWithWarnings = { ->
delegate.validate()
if (delegate.hasErrors()) {
def message = new StringBuilder(
"problem ${delegate.id ? 'updating' : 'creating'} ${delegate.getClass().simpleName}: $delegate")
def locale = Locale.getDefault()
for (fieldErrors in delegate.errors) {
for (error in fieldErrors.allErrors) {
message.append("\n\t")
message.append(messageSource.getMessage(error, locale))
}
}
log.warn message
delegate.discard()
return false
}
return true
}
}
}
}
This depends on a 'log' variable being in scope, which will be true in any Grails artifact. This changes the controller usage slightly:
class MyController {
def actionName = {
def thing = new Thing(params)
if (thing.saveOrUpdate()) {
redirect action: 'show', id: thing.id
}
else {
render view: 'create', model: [thing: thing]
}
}
}
As a metaclass method it may make more sense to rename it, e.g. saveWithWarnings().

asp.net mvc related, mainly a refactor question

can anyone think of a better way to do this?
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction()
{
NameValueDeserializer value = new NameValueDeserializer();
// selected messages
MemberMessageSaveAction[] messages = (MemberMessageSaveAction[])value.Deserialize(Request.Form, "value", typeof(MemberMessageSaveAction[]));
// selected action
MemberMessageAction action = (MemberMessageAction)Enum.Parse(typeof(MemberMessageAction), Request.Form["action"]);
// determine action
if (action != MemberMessageAction.MarkRead &&
action != MemberMessageAction.MarkUnRead &&
action != MemberMessageAction.Delete)
{
// selected action requires special processing
IList<MemberMessage> items = new List<MemberMessage>();
// add selected messages to list
for (int i = 0; i < messages.Length; i++)
{
foreach (int id in messages[i].Selected)
{
items.Add(MessageRepository.FetchByID(id));
}
}
// determine action further
if (action == MemberMessageAction.MoveToFolder)
{
// folders
IList<MemberMessageFolder> folders = FolderRepository.FetchAll(new MemberMessageFolderCriteria
{
MemberID = Identity.ID,
ExcludedFolder = Request.Form["folder"]
});
if (folders.Total > 0)
{
ViewData["messages"] = items;
ViewData["folders"] = folders;
return View("move");
}
return Url<MessageController>(c => c.Index("inbox", 1)).Redirect();
}
else if (action == MemberMessageAction.ExportXml)
{
return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Xml);
}
else if (action == MemberMessageAction.ExportCsv)
{
return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Csv);
}
else
{
return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Text);
}
}
else if (action == MemberMessageAction.Delete)
{
for (int i = 0; i < messages.Length; i++)
{
foreach (int id in messages[i].Selected)
{
MemberMessage message = MessageRepository.FetchByID(id);
if (message.Sender.ID == Identity.ID || message.Receiver.ID == Identity.ID)
{
if (message.Sender.ID == Identity.ID)
{
message.SenderActive = false;
}
else
{
message.ReceiverActive = false;
}
message.Updated = DateTime.Now;
MessageRepository.Update(message);
if (message.SenderActive == false && message.ReceiverActive == false)
{
MessageRepository.Delete(message);
}
}
}
}
}
else
{
for (int i = 0; i < messages.Length; i++)
{
foreach (int id in messages[i].Selected)
{
MemberMessage message = MessageRepository.FetchByID(id);
if (message.Receiver.ID == Identity.ID)
{
if (action == MemberMessageAction.MarkRead)
{
message.ReceiverRead = true;
}
else
{
message.ReceiverRead = false;
}
message.Updated = DateTime.Now;
MessageRepository.Update(message);
}
}
}
}
return Url<MessageController>(c => c.Index("inbox", 1)).Redirect();
}
I think you can also leverage the mvc framework for most of your code. Correct me if I'm wrong because I'm gonna make a few assumptions about your classes because I can't deduct it from your post.
My assumptions:
Request.Form["action"] is a single value selectbox
Request.Form["value"] is a multy value selectbox
action is the kind of action you want to be taken on all the messages
message is the list of values that should go with the action
I would try to leverage the framework's functionality where possible
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveMemberAction(SelectList selectedMessages, MemberMessageAction actionType){
//Refactors mentioned by others
}
If you then give your inputs in your Html the correct name (in my example that would be selectedMessages and actionType) the first few rules become unnessecary.
If the default modelBinder cannot help you, you might want to consider putting the parsing logic in a custom modelbinder. You can search SO for posts about it.
As a side note: you might want to reconsider your variable namings. "action" might be confusing with MVC's action (like in ActionResult) and MemberMessageSaveAction might look like it's a value of MemberMessageAction enum. Just a thought.
The first step will be making different methods for each action.
Next is to remove the negative logic.
This results in something like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction() {
// SNIP
if (action == MemberMessageAction.Delete) {
return DoDeleteAction(...);
}
else if (action == MemberMessageAction.MoveToFolder) {
return DoMoveToFolderAction(...);
}
else if (action == MemberMessageAction.ExportXml) {
return DoExportXmlAction(...);
}
else if (action == MemberMessageAction.ExportCsv) {
return DoExportCsvAction(...);
}
else {
return HandleUnknownAction(...);
}
}
Turn MemberMessageAction into a class that has a Perform virtual function.
For your Special actions, group the common Perform code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction()
{
NameValueDeserializer value = new NameValueDeserializer();
MemberMessageSaveAction[] messages = (MemberMessageSaveAction[])value.Deserialize(Request.Form, "value", typeof(MemberMessageSaveAction[]));
MemberMessageAction action = MemberMessageAction.FromName(
messages,
Request.Form["action"]));
return action.Perform();
}
class MoveToFolder : SpecialAction { /*...*/ }
class ExportXml : SpecialAction { /*...*/ }
class ExportCsv : SpecialAction { /*...*/ }
class Delete : MemberMessageAction { /*...*/ }
class MarkRead : MemberMessageAction { /*...*/ }
class MarkUnRead : MemberMessageAction { /*...*/ }
abstract class MemberMessageAction {
protected MemberMessageSaveAction[] messages;
public MemberMessageAction(MemberMessageSaveAction[] ms) { messages = ms; }
public abstract ActionResult Perform();
public static MemberMessageAction FromName(MemberMessageSaveAction[] ms, string action) {
// stupid code
// return new Delete(ms);
}
}
abstract class SpecialAction : MemberMessageAction {
protected IList<MemberMessage> items;
public SpecialAction(MemberMessageSaveAction[] ms) : base(ms) {
// Build items
}
}
Now you can easily factor the code.
I don't like
MessageRepository.FetchByID(messages[i].ID)
this will make messages.Length (selected) queries to the database. I think you need to store your messages in ViewData, perform a filtering and pass them to Update() without the need to requery your database.
I came up with this.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update(MemberMessageUpdate[] messages, MemberMessage.Action action)
{
var actions = new List<MemberMessage.Action>
{
MemberMessage.Action.MoveToFolder,
MemberMessage.Action.ExportCsv,
MemberMessage.Action.ExportText,
MemberMessage.Action.ExportText
};
if (actions.Contains(action))
{
IList<MemberMessage> items = new List<MemberMessage>();
for (var i = 0; i < messages.Length; i++)
{
if (messages[i].Selected == false)
{
continue;
}
items.Add(MessageRepository.FetchByID(messages[i].ID));
}
if (action == MemberMessage.Action.MoveToFolder)
{
var data = new MessageMoveViewData
{
Messages = items
};
return View("move", data);
}
return new MessageDownloadResult(Identity.ID, items, action);
}
MessageRepository.Update(messages, action);
return Url<MessageController>(c => c.Index(null, null, null, null)).Redirect();
}

Resources