Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Java Data types used in server DSResponses

    Hi Isomorphic,

    I have this setting in current 5.0p:
    A user table, where the Admin may change all users and the currently logged in user may just change some of its own fields (email, telephone, passwd).

    I can restrict the access to the needed operationIds via Declarative Security on operationBinding level and via DMI.
    I can't restrict access / don't like to restrict access on a field-level with Declarative Security (too much allowed roles, cluttering of .ds.xml file).

    So I want to check which fields in the request are different to current DB-values. This is what I have:

    Code:
    public class T_USER {
    public DSResponse updateOwnUserSettings(DSRequest dsRequest, HttpServletRequest servletRequest) throws Exception {
    Long userId = (dsRequest.getValues().get("ID") == null) ? null : Long.parseLong(dsRequest.getValues().get("ID").toString());
    if (userId == null)
    return new DSResponse(dsRequest.getDataSource()).setFailure("No User in request!");
    
    if (User.getUserId(servletRequest) != userId) // Gets user id from session
    return new DSResponse(dsRequest.getDataSource()).setFailure("Only update to currently logged user allowed!");
    
    DSRequest userCurrentRequest = new DSRequest(DatasourceEnum.T_USER.getValue(), DataSource.OP_FETCH, dsRequest.getRPCManager());
    userCurrentRequest.addToCriteria(new SimpleCriterion("ID", DefaultOperators.Equals, userId));
    DSResponse userCurrentResponse = userCurrentRequest.execute();
    
    String loginname = userCurrentResponse.getRecord().get("LOGINNAME").toString();
    if (dsRequest.getValues().get("LOGINNAME") == null || !dsRequest.getValues().get("LOGINNAME").toString().equals(loginname))
    return new DSResponse(dsRequest.getDataSource()).setFailure("Tried to change loginname. Not allowed.");
    // I don't want to to this for all fields...
    
    
    @SuppressWarnings("unchecked")
    List<String> changedFields = checkChangedFields((Map<String, Object>) dsRequest.getValues(), userCurrentResponse.getRecord());
    
    changedFields.remove("EMAIL");
    changedFields.remove("PHONENUMBER");
    changedFields.remove("BCRYPTHASH");
    changedFields.remove("PASSWORD1");
    changedFields.remove("PASSWORD2");
    
    if (!changedFields.isEmpty())
    return new DSResponse(dsRequest.getDataSource()).setFailure("Tried to change these fields:" + join(changedFields, ","));
    
    hashPW(dsRequest);
    return dsRequest.execute();
    };
    
    private List<String> checkChangedFields(Map<String, Object> request, Map<String, Object> dbRow) {
    ArrayList<String> retList = new ArrayList<String>();
    
    for (Map.Entry<String, Object> : request) {
    // What to do here
    }
    return retList;
    }
    
    static public String join(List<String> list, String conjunction) {
    StringBuilder sb = new StringBuilder();
    boolean first = true;
    for (String item : list) {
    if (first)
    first = false;
    else
    sb.append(conjunction);
    sb.append(item);
    }
    return sb.toString();
    }
    };
    Please see "// What to do here".
    I need to check all request-values against the dbRow-values.
    I assume that the dsRequest.getValues() is Map<String, Object>, although it is not typed. Is that correct? If so, what types to expect inside Object?
    For the dbRow, can I assume that all fields will have a Java type out of this list (I'm using Oracle 11.2)?

    Best regards
    Blama

    &#194;&#160;

    #2
    First of all we recommend you use the field level security to implement this as even though you feel like you are cluttering you XML datasource files as you will be using tested code which we know works, instead you are now "cluttering" your server side code with additional functionality for a specific use case.

    Now when it comes to getValues(), it will depend slightly based on the operation of the request, see&#194;&#160;DSRequest.getValues()&#194;&#160;for more information on that. In most cases this will be a Map<String, Object> representing the record/data being added/updated. The types of the values in this map will have been determined through automatic conversion using&#194;&#160;DataTools.setProperties(). For the DSResponse a very similar process is in place in order to map types from the actual database record, see&#194;&#160;DataSource.setProperties()&#194;&#160;for more information. All in all an equals() check on the two values should work.

    Comment

    Working...
    X