Changeset 538
- Timestamp:
- Jun 7, 2010, 4:39:11 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/studycapturing/TemplateEditorController.groovy
r385 r538 19 19 20 20 class TemplateEditorController { 21 /** 22 * index closure 23 */ 21 def entityName; 22 def entity; 23 24 /** 25 * index closure 26 */ 24 27 def index = { 25 // got a entity get parameter? 26 def entity = null 27 if (params.entity) { 28 // decode entity get parameter 29 if (grailsApplication.config.crypto) { 30 // generate a Blowfish encrypted and Base64 encoded string. 31 entity = Blowfish.decryptBase64( 32 params.entity, 33 grailsApplication.config.crypto.shared.secret 34 ) 35 } else { 36 // base64 only; this is INSECURE! Even though it is not 37 // very likely, it is possible to exploit this and have 38 // Grails dynamically instantiate whatever class you like. 39 // If that constructor does something harmfull this could 40 // be dangerous. Hence, use encryption (above) instead... 41 entity = new String(params.entity.toString().decodeBase64()) 42 } 43 } 28 // Check whether a right entity is given 29 _checkEntity(); 44 30 45 // go with the flow! 46 redirect(action: 'pages', params:["entity":entity]) 31 // fetch all templates for this entity 32 def templates = Template.findAllByEntity(entity) 33 34 // Check whether a template is already selected 35 def selectedTemplate = params.template; 36 def template = null; 37 38 if( selectedTemplate ) { 39 template = Template.get( selectedTemplate ); 40 } 41 42 return [ 43 entity: entity, 44 templates: templates, 45 encryptedEntity: params.entity, 46 fieldTypes: TemplateFieldType.list(), 47 48 template: template 49 ]; 47 50 } 48 51 49 /** 50 * Webflow 51 */ 52 def pagesFlow = { 53 // start the flow 54 start { 55 action { 56 // define initial flow variables 57 flow.entity = null 58 flow.templates = [] 52 /** 53 * Updates a selected template field using a AJAX call 54 */ 55 def update = { 56 // Search for the template field 57 def templateField = TemplateField.get( params.id ); 58 if( !templateField ) { 59 response.status = 404; 60 render 'TemplateField not found'; 61 return; 62 } 59 63 60 // define success variable 61 def errors = true 64 // Update the field if it is not updated in between 65 if (params.version) { 66 def version = params.version.toLong() 67 if (templateField.version > version) { 68 response.status = 500; 69 render 'TemplateField was updated while you were working on it. Please reload and try again.'; 70 return 71 } 72 } 73 templateField.properties = params 74 if (!templateField.hasErrors() && templateField.save(flush: true)) { 75 render ''; 76 } else { 77 response.status = 500; 78 render 'TemplateField was not updated because errors occurred.'; 79 return 80 } 81 } 62 82 63 // got an entity parameter? 64 if (params.entity && params.entity instanceof String) { 65 // yes, try to dynamicall load the entity 66 try { 67 // dynamically load the entity 68 def entity = Class.forName(params.entity, true, this.getClass().getClassLoader()) 83 /** 84 * Shows an error page 85 * 86 * TODO: improve the error page 87 */ 88 def error = { 89 render( 'view': 'error' ); 90 } 69 91 70 // succes, is entity an instance of TemplateEntity? 71 if (entity.superclass =~ /TemplateEntity$/) { 72 errors = false 92 /** 93 * Moves a template field using a AJAX call 94 * 95 * 96 */ 97 def move = { 98 // Search for the template 99 def template = Template.get( params.template ); 73 100 74 // yes, assign entity to the flow 75 flow.entity = entity 101 if( !template ) { 102 response.status = 404; 103 render 'Template not found'; 104 return; 105 } 76 106 77 // fetch all templates to this entity 78 flow.templates = Template.findAllByEntity(entity) 79 80 // find all template fields for this particular entity 81 // for now, all 82 // TODO: limit for this entity only 83 flow.allTemplateFields = TemplateField.findAll().sort{ it.name } 84 } 85 } catch (Exception e) { } 86 } 107 // Search for the template field 108 def templateField = TemplateField.get( params.templateField ); 109 if( !templateField ) { 110 response.status = 404; 111 render 'TemplateField not found'; 112 return; 113 } 87 114 88 // success? 89 if (errors) { 90 error() 91 } else { 92 success() 93 } 94 } 95 on("success").to "templates" 96 on("error").to "errorInvalidEntity" 97 } 115 // The template field should exist within the template 116 if( !template.fields.contains( templateField ) ) { 117 response.status = 404; 118 render 'TemplateField not found within template'; 119 return; 120 } 98 121 99 // could not dynamically load entity, possible hack 100 // or invalid entity specified in template field 101 errorInvalidEntity { 102 render(view: "errorInvalidEntity") 103 } 122 // Move the item 123 def currentIndex = template.fields.indexOf( templateField ); 124 def moveField = template.fields.remove( currentIndex ); 125 template.fields.add( Integer.parseInt( params.position ), moveField ); 104 126 105 // main template editor page 106 templates { 107 render(view: "templates") 108 onRender { 109 // template parameter given? 110 if (params.template) { 111 // yes, find template by name 112 flow.template = Template.findByName(params.template) 113 flow.templateFields = flow.allTemplateFields 127 render ""; 128 } 114 129 115 flow.template.fields.each() { 116 println it 117 flow.templateFields.remove(it) 118 119 } 120 println "count: "+flow.template.fields.size() 130 /** 131 * Checks whether a correct entity is given 132 */ 133 def _checkEntity = { 134 // got a entity get parameter? 135 entityName = _parseEntityType(); 121 136 122 println "---" 123 flow.allTemplateFields.each() { 124 println it 125 } 126 println "count: "+flow.allTemplateFields.size() 127 println "---" 137 if( !entityName ) { 138 error(); 139 return; 140 } 128 141 129 println flow.allTemplateFields.class 130 println flow.template.fields.class 131 println "---" 132 } 133 } 134 on("next").to "start" 135 } 136 } 142 // Create an object of this type 143 entity = _getEntity( entityName ); 144 145 if( !entity ) { 146 error(); 147 return; 148 } 149 150 return true; 151 } 152 153 154 /** 155 * Checks whether the entity type is given and can be parsed 156 */ 157 def _parseEntityType() { 158 def entityName; 159 if (params.entity) { 160 // decode entity get parameter 161 if (grailsApplication.config.crypto) { 162 // generate a Blowfish encrypted and Base64 encoded string. 163 entityName = Blowfish.decryptBase64( 164 params.entity, 165 grailsApplication.config.crypto.shared.secret 166 ) 167 } else { 168 // base64 only; this is INSECURE! Even though it is not 169 // very likely, it is possible to exploit this and have 170 // Grails dynamically instantiate whatever class you like. 171 // If that constructor does something harmfull this could 172 // be dangerous. Hence, use encryption (above) instead... 173 entityName = new String(params.entity.toString().decodeBase64()) 174 } 175 176 return entityName; 177 } else { 178 return false; 179 } 180 } 181 182 /** 183 * Creates an object of the given entity. Returns false is the entity 184 * is not a subclass of TemplateEntity 185 */ 186 def _getEntity( entityName ) { 187 // Find the templates 188 def entity = Class.forName(entityName, true, this.getClass().getClassLoader()) 189 190 // succes, is entity an instance of TemplateEntity? 191 if (entity.superclass =~ /TemplateEntity$/) { 192 return entity; 193 } else { 194 return false; 195 } 196 197 } 137 198 } -
trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy
r536 r538 21 21 Map templateDoubleFields = [:] 22 22 Map templateDateFields = [:] 23 Map templateRelTimeFields = [:] // Contains relative times in seconds 23 24 25 // N.B. If you try to set Long.MIN_VALUE for a reltime field, an error will occur 26 // However, this will never occur in practice: this value represents 3 bilion centuries 27 Map templateRelTimeFields = [:] // Contains relative times in seconds 24 28 Map templateFileFields = [:] // Contains filenames 25 29 Map templateTermFields = [:] … … 209 213 def error = false 210 214 fields.each { key, value -> 211 if (value && value.class != long) { 215 if( value && value == Long.MIN_VALUE ) { 216 error = true 217 errors.rejectValue( 218 'templateRelTimeFields', 219 'templateEntity.typeMismatch.reltime', 220 [key, value] as Object[], 221 'Value cannot be parsed for property {0}' 222 ) 223 } else if (value && value.class != long) { 212 224 try { 213 225 fields[key] = (value as long) … … 423 435 // 424 436 if (field.type == TemplateFieldType.RELTIME && value != null && value.class == String) { 425 // A string was given, attempt to transform it into a timespan 426 value = RelTime.parseRelTime(value).getValue(); 437 // A string was given, attempt to transform it into a timespan 438 // If it cannot be parsed, set the lowest possible value of Long. 439 // The validator method will raise an error 440 // 441 // N.B. If you try to set Long.MIN_VALUE itself, an error will occur 442 // However, this will never occur: this value represents 3 bilion centuries 443 try { 444 value = RelTime.parseRelTime(value).getValue(); 445 } catch( IllegalArgumentException e ) { 446 value = Long.MIN_VALUE; 447 } 427 448 } 428 449 -
trunk/grails-app/views/layouts/dialog.gsp
r436 r538 7 7 <link rel="stylesheet" href="${resource(dir: 'css', file: 'dialog.css')}"/> 8 8 <g:javascript library="jquery"/> 9 <script type="text/javascript">var baseUrl = '${resource(dir: '')}';</script> 9 10 <script src="${createLinkTo(dir: 'js', file: 'jquery-ui-1.8.1.custom.min.js')}" type="text/javascript"></script> 10 11 <link rel="stylesheet" href="${createLinkTo(dir: 'css/cupertino', file: 'jquery-ui-1.8.1.custom.css')}"/> -
trunk/grails-app/views/templateEditor/elements/_all.gsp
r496 r538 1 <li class="ui-state-default"> 2 <span class="ui-icon ui-icon-arrowthick-2-n-s"></span><b>${it.name}</b> 3 ( <g:render template="elements/${it.type.toString().toLowerCase().replaceAll(/ /,'_')}" /> ) 1 <li class="ui-state-default" id="templateField_${it.id}"> 2 <span class="ui-icon ui-icon-arrowthick-2-n-s"></span> 3 <b>${it.name}</b> 4 (<g:render template="elements/${it.type.toString().toLowerCase().replaceAll(/ /,'_')}" />) 5 6 <form class="templateField_form" id="templateField_${it.id}_form" action="update"> 7 <g:hiddenField name="id" value="${it.id}" /> 8 <g:hiddenField name="version" value="${it.version}" /> 9 <label for="name">Name:</label> <g:textField name="name" value="${it.name}" /><br /> 10 <label for="type">Type:</label> <g:select from="${fieldTypes}" name="type" value="${it.type}" /><br /> 11 <label for="unit">Unit:</label> <g:textField name="unit" value="${it.unit}" /><br /> 12 <label for="comment">Comment:</label> <g:textArea name="comment" value="${it.comment}" /><br /> 13 <label for="required">Required:</label> <g:checkBox name="required" value="${it.required}" /><br /> 14 15 <input type="button" value="Save" onClick="updateTemplateField( ${it.id} );"> 16 <input type="button" value="Delete" onClick=""> 17 <input type="button" value="Close" onClick="hideTemplateFieldForm( ${it.id} );"> 18 </form> 4 19 </li>
Note: See TracChangeset
for help on using the changeset viewer.