improve validation

This commit is contained in:
Sebastian Sdorra
2010-11-13 11:12:14 +01:00
parent 3729229843
commit c9295b9a2d
11 changed files with 400 additions and 34 deletions

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm;
/**
*
* @author Sebastian Sdorra
*/
public interface Validateable
{
/**
* Method description
*
*
* @return
*/
public boolean isValid();
}

View File

@@ -29,11 +29,12 @@
* *
*/ */
package sonia.scm.repository; package sonia.scm.repository;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import sonia.scm.HandlerEvent;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@@ -41,8 +42,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.ConfigurationException; import sonia.scm.ConfigurationException;
import sonia.scm.HandlerEvent;
import sonia.scm.SCMContext; import sonia.scm.SCMContext;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.Type;
import sonia.scm.util.AssertUtil; import sonia.scm.util.AssertUtil;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
@@ -57,7 +60,6 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import sonia.scm.Type;
/** /**
* *
@@ -93,31 +95,6 @@ public class BasicRepositoryManager extends AbstractRepositoryManager
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
private void addHandler(RepositoryHandler handler)
{
AssertUtil.assertIsNotNull(handler);
Type type = handler.getType();
AssertUtil.assertIsNotNull(type);
if (handlerMap.containsKey(type.getName()))
{
throw new ConfigurationException(
type.getName().concat("allready registered"));
}
if (logger.isInfoEnabled())
{
logger.info("added RepositoryHandler {} for type {}", handler.getClass(),
type);
}
handlerMap.put(type.getName(), handler);
handler.init(SCMContext.getContext());
types.add(type);
}
/** /**
* Method description * Method description
* *
@@ -152,6 +129,7 @@ public class BasicRepositoryManager extends AbstractRepositoryManager
repository.getType()); repository.getType());
} }
AssertUtil.assertIsValid(repository);
getHandler(repository).create(repository); getHandler(repository).create(repository);
fireEvent(repository, HandlerEvent.CREATE); fireEvent(repository, HandlerEvent.CREATE);
} }
@@ -207,6 +185,7 @@ public class BasicRepositoryManager extends AbstractRepositoryManager
repository.getType()); repository.getType());
} }
AssertUtil.assertIsValid(repository);
getHandler(repository).modify(repository); getHandler(repository).modify(repository);
fireEvent(repository, HandlerEvent.MODIFY); fireEvent(repository, HandlerEvent.MODIFY);
} }
@@ -322,6 +301,41 @@ public class BasicRepositoryManager extends AbstractRepositoryManager
return types; return types;
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param handler
*/
private void addHandler(RepositoryHandler handler)
{
AssertUtil.assertIsNotNull(handler);
Type type = handler.getType();
AssertUtil.assertIsNotNull(type);
if (handlerMap.containsKey(type.getName()))
{
throw new ConfigurationException(
type.getName().concat("allready registered"));
}
if (logger.isInfoEnabled())
{
logger.info("added RepositoryHandler {} for type {}", handler.getClass(),
type);
}
handlerMap.put(type.getName(), handler);
handler.init(SCMContext.getContext());
types.add(type);
}
//~--- get methods ----------------------------------------------------------
/** /**
* Method description * Method description
* *

View File

@@ -36,7 +36,9 @@ package sonia.scm.repository;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import sonia.scm.TypedObject; import sonia.scm.TypedObject;
import sonia.scm.Validateable;
import sonia.scm.util.Util; import sonia.scm.util.Util;
import sonia.scm.util.ValidationUtil;
import sonia.scm.xml.XmlTimestampDateAdapter; import sonia.scm.xml.XmlTimestampDateAdapter;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -64,7 +66,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
"id", "type", "name", "contact", "description", "creationDate", "url", "id", "type", "name", "contact", "description", "creationDate", "url",
"permissions" "permissions"
}) })
public class Repository implements TypedObject, Serializable public class Repository implements TypedObject, Validateable, Serializable
{ {
/** Field description */ /** Field description */
@@ -231,6 +233,20 @@ public class Repository implements TypedObject, Serializable
return url; return url;
} }
/**
* Method description
*
*
* @return
*/
@Override
public boolean isValid()
{
return Util.isNotEmpty(name) && Util.isNotEmpty(type)
&& ((Util.isEmpty(contact))
|| ValidationUtil.isMailAddressValid(contact));
}
//~--- set methods ---------------------------------------------------------- //~--- set methods ----------------------------------------------------------
/** /**

View File

@@ -136,6 +136,7 @@ public class BasicUserManager implements UserManager
logger.info("create user {} of type {}", user.getName(), user.getType()); logger.info("create user {} of type {}", user.getName(), user.getType());
} }
AssertUtil.assertIsValid(user);
getHandler(user).create(user); getHandler(user).create(user);
fireEvent(user, HandlerEvent.CREATE); fireEvent(user, HandlerEvent.CREATE);
} }
@@ -154,7 +155,7 @@ public class BasicUserManager implements UserManager
{ {
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
{ {
logger.info("create user {} of type {}", user.getName(), user.getType()); logger.info("delete user {} of type {}", user.getName(), user.getType());
} }
getHandler(user).delete(user); getHandler(user).delete(user);
@@ -193,6 +194,7 @@ public class BasicUserManager implements UserManager
logger.info("modify user {} of type {}", user.getName(), user.getType()); logger.info("modify user {} of type {}", user.getName(), user.getType());
} }
AssertUtil.assertIsValid(user);
getHandler(user).modify(user); getHandler(user).modify(user);
fireEvent(user, HandlerEvent.MODIFY); fireEvent(user, HandlerEvent.MODIFY);
} }

View File

@@ -36,6 +36,9 @@ package sonia.scm.user;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import sonia.scm.TypedObject; import sonia.scm.TypedObject;
import sonia.scm.Validateable;
import sonia.scm.util.Util;
import sonia.scm.util.ValidationUtil;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -58,7 +61,8 @@ import javax.xml.bind.annotation.XmlType;
{ {
"name", "displayName", "mail", "password", "type" "name", "displayName", "mail", "password", "type"
}) })
public class User implements TypedObject, Principal, Cloneable, Serializable public class User
implements TypedObject, Principal, Cloneable, Validateable, Serializable
{ {
/** Field description */ /** Field description */
@@ -263,6 +267,20 @@ public class User implements TypedObject, Principal, Cloneable, Serializable
return type; return type;
} }
/**
* Method description
*
*
* @return
*/
@Override
public boolean isValid()
{
return Util.isNotEmpty(name) && Util.isNotEmpty(displayName)
&& Util.isNotEmpty(type)
&& ((Util.isEmpty(mail)) || ValidationUtil.isMailAddressValid(mail));
}
//~--- set methods ---------------------------------------------------------- //~--- set methods ----------------------------------------------------------
/** /**

View File

@@ -29,8 +29,14 @@
* *
*/ */
package sonia.scm.util; package sonia.scm.util;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.Validateable;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.util.Collection; import java.util.Collection;
@@ -97,4 +103,20 @@ public class AssertUtil
throw new IllegalStateException("object is required"); throw new IllegalStateException("object is required");
} }
} }
/**
* Method description
*
*
* @param validateable
*/
public static void assertIsValid(Validateable validateable)
{
assertIsNotNull(validateable);
if (!validateable.isValid())
{
throw new IllegalStateException("object is not valid");
}
}
} }

View File

@@ -0,0 +1,110 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.util;
/**
*
* @author Sebastian Sdorra
*/
public class ValidationUtil
{
/** Field description */
private static final String REGEX_MAIL =
"^[A-z0-9][\\w.-]*@[A-z0-9][\\w\\-\\.]+\\.[A-z0-9]{2,6}$";
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param value
*
* @return
*/
public static boolean isFilenameValid(String value)
{
AssertUtil.assertIsNotNull(value);
return isNotContaining(value, "/", "\\", ":");
}
/**
* Method description
*
*
* @param value
*
* @return
*/
public static boolean isMailAddressValid(String value)
{
AssertUtil.assertIsNotNull(value);
return value.matches(REGEX_MAIL);
}
/**
* Method description
*
*
* @param value
* @param notAllowedStrings
*
* @return
*/
public static boolean isNotContaining(String value,
String... notAllowedStrings)
{
AssertUtil.assertIsNotNull(value);
boolean result = true;
if (notAllowedStrings != null)
{
for (String nas : notAllowedStrings)
{
if (value.indexOf(nas) >= 0)
{
result = false;
break;
}
}
}
return result;
}
}

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.util;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author Sebastian Sdorra
*/
public class ValidationUtilTest
{
/**
* Method description
*
*/
@Test
public void testIsFilenameValid()
{
// true
assertTrue(ValidationUtil.isFilenameValid("test"));
assertTrue(ValidationUtil.isFilenameValid("test 123"));
// false
assertFalse(ValidationUtil.isFilenameValid("../../"));
assertFalse(ValidationUtil.isFilenameValid("test/../.."));
assertFalse(ValidationUtil.isFilenameValid("\\ka"));
assertFalse(ValidationUtil.isFilenameValid("ka:on"));
}
/**
* Method description
*
*/
@Test
public void testIsMailAddressValid()
{
// true
assertTrue(ValidationUtil.isMailAddressValid("s.sdorra@ostfalia.de"));
assertTrue(ValidationUtil.isMailAddressValid("sdorra@ostfalia.de"));
assertTrue(ValidationUtil.isMailAddressValid("s.sdorra@hbk-bs.de"));
assertTrue(ValidationUtil.isMailAddressValid("s.sdorra@gmail.com"));
// false
assertFalse(ValidationUtil.isMailAddressValid("ostfalia.de"));
assertFalse(ValidationUtil.isMailAddressValid("@ostfalia.de"));
assertFalse(ValidationUtil.isMailAddressValid("s.sdorra@"));
assertFalse(ValidationUtil.isMailAddressValid("s.sdorra@ostfalia"));
assertFalse(ValidationUtil.isMailAddressValid("s.sdorra@@ostfalia.de"));
assertFalse(ValidationUtil.isMailAddressValid("s.sdorra@ ostfalia.de"));
assertFalse(ValidationUtil.isMailAddressValid("s.sdorra @ostfalia.de"));
}
/**
* Method description
*
*/
@Test
public void testIsNotContaining()
{
// true
assertTrue(ValidationUtil.isNotContaining("test", "abc"));
// false
assertFalse(ValidationUtil.isNotContaining("test", "e"));
assertFalse(ValidationUtil.isNotContaining("test", "e", "s"));
assertFalse(ValidationUtil.isNotContaining("test", "es"));
assertFalse(ValidationUtil.isNotContaining("test", "t"));
}
}

View File

@@ -88,3 +88,5 @@ function logout(){
} }
}); });
} }
Ext.QuickTips.init();

View File

@@ -147,7 +147,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
allowBlank: false allowBlank: false
}, },
{fieldLabel: 'Contact', name: 'contact'}, {fieldLabel: 'Contact', name: 'contact', vtype: 'email'},
{fieldLabel: 'Description', name: 'description', xtype: 'textarea'} {fieldLabel: 'Description', name: 'description', xtype: 'textarea'}
] ]
}; };

View File

@@ -78,6 +78,19 @@ Sonia.user.Grid = Ext.extend(Sonia.rest.Grid, {
// register xtype // register xtype
Ext.reg('userGrid', Sonia.user.Grid); Ext.reg('userGrid', Sonia.user.Grid);
Ext.apply(Ext.form.VTypes, {
password: function(val, field) {
if (field.initialPassField) {
var pwd = Ext.getCmp(field.initialPassField);
return (val == pwd.getValue());
}
return true;
},
passwordText: 'The passwords entered do not match!'
});
// UserFormPanel // UserFormPanel
Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
@@ -95,14 +108,24 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
},{ },{
fieldLabel: 'Mail', fieldLabel: 'Mail',
name: 'mail', name: 'mail',
allowBlank: false allowBlank: false,
vtype: 'email'
},{ },{
fieldLabel: 'Password', fieldLabel: 'Password',
id: 'pwd',
name: 'password', name: 'password',
inputType: 'password' inputType: 'password',
minLength: 6,
maxLength: 32,
minLengthText: 'Password must be at least 6 characters long.'
},{ },{
name: 'password', name: 'password',
inputType: 'password' inputType: 'password',
minLength: 6,
maxLength: 32,
minLengthText: 'Password must be at least 6 characters long.',
vtype: 'password',
initialPassField: 'pwd'
}] }]
}; };