- Timestamp:
- 2021-08-16T20:17:05+12:00 (3 years ago)
- Location:
- main/trunk/greenstone3/src/java/org/greenstone/gsdl3
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/Authentication.java
r35288 r35298 163 163 protected static final String COLLECTION = "collection"; 164 164 protected static final String GROUPS = "groups"; 165 protected static final String COMPACTED_GROUPS = "compacted_groups"; 165 166 protected static final String EXPANDED_GROUPS = "expanded_groups"; 166 167 protected static final String STATUS = "status"; … … 576 577 } 577 578 logger.debug("username="+username+", groups = "+groups); 579 logger.debug("expandedGroups would be: "+UserTermInfo.expandGroups(groups)); 580 logger.debug("compactedGroups would be: "+UserTermInfo.compactGroups(groups)); 581 578 582 if ((userInformation == null || username == null) && _userOpList.contains(op)) 579 583 { … … 788 792 } 789 793 790 groups = null; 794 groups = null; // doesn't matter if local groups var keeps value in compactedGroups or expandedGroups form, 795 // as addUser() and addUserInformationToNode() will ensure use of expanded and compacted forms respectively 791 796 String status = null; 792 797 String comment = null; … … 798 803 799 804 } else { 800 groups = retrieveDataForUser(previousUsername, GROUPS);805 groups = retrieveDataForUser(previousUsername, EXPANDED_GROUPS); 801 806 status = retrieveDataForUser(previousUsername, STATUS); 802 807 comment = retrieveDataForUser(previousUsername, COMMENT); … … 872 877 873 878 DerbyWrapper derbyWrapper = openDatabase(); 874 String chpa_groups = retrieveDataForUser(user_name, GROUPS);879 String chpa_groups = retrieveDataForUser(user_name, EXPANDED_GROUPS); // userDB now stores expandedGroups, not compactedGroups 875 880 String chpa_comment = "password_changed_by_user"; 876 881 String info = derbyWrapper.modifyUserInfo(user_name, hashPassword(newPassword), chpa_groups, null, chpa_comment, null); … … 1079 1084 for (int i = 0; i < userQueryResult.getSize(); i++) 1080 1085 { 1086 // can call either getExpandedGroups() or getOrigGroups() to check admin group is in there: 1081 1087 if (((UserTermInfo) userInfo.get(i)).getOrigGroups() != null && ((UserTermInfo) userInfo.get(i)).getOrigGroups().matches(".*\\badministrator\\b.*")) 1082 1088 { … … 1138 1144 { 1139 1145 newGroups = newGroups.replaceAll(" ", ""); 1146 // store only expandedGroups in DB now 1147 newGroups = UserTermInfo.expandGroups(newGroups); 1140 1148 1141 1149 //Check if the user already exists … … 1207 1215 break; 1208 1216 } 1209 else if (dataType.equals( GROUPS))1217 else if (dataType.equals(COMPACTED_GROUPS)) 1210 1218 { 1211 1219 data = ((UserTermInfo) userInfo.get(i)).getOrigGroups(); … … 1252 1260 Element user_node = doc.createElement(GSXML.USER_NODE_ELEM); 1253 1261 String username = ((UserTermInfo) userInfo.get(i)).getUsername(); 1254 String groups = ((UserTermInfo) userInfo.get(i)).getOrigGroups();1255 // Retrieve original (stored, user-entered) and not expandedgroups1256 // a s getUserNodeList only used in addUserInformationToNode() which1257 // allows displaying and modifying user info pages 1258 // and authenticating admin user which doesn't requireexpanded groups.1262 String compactedGroups = ((UserTermInfo) userInfo.get(i)).getOrigGroups(); 1263 // Since this is used for display in admin pages, get compacted (more similar to user-entered) groups 1264 // and not expanded groups, as getUserNodeList only used in addUserInformationToNode() which 1265 // allows displaying and modifying user info pages and authenticating admin user, 1266 // none of which requires expanded groups. 1259 1267 String accountstatus = ((UserTermInfo) userInfo.get(i)).getAccountStatus(); 1260 1268 String comment = ((UserTermInfo) userInfo.get(i)).getComment(); 1261 1269 String email = ((UserTermInfo) userInfo.get(i)).getEmail(); 1262 1270 user_node.setAttribute(USERNAME, username); 1263 user_node.setAttribute(GROUPS, groups);1271 user_node.setAttribute(GROUPS, compactedGroups); 1264 1272 user_node.setAttribute(STATUS, accountstatus); 1265 1273 user_node.setAttribute(COMMENT, comment); -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DerbyWrapper.java
r30240 r35298 33 33 import org.greenstone.util.GlobalProperties; 34 34 35 /** 36 * The UserDB stores the groups in the "roles" table in expanded form, i.e. expandedGroups. 37 * This is what is retrieved as well. Call UserTermInfo.compactGroup(expandedGroups) 38 * to get the compacted form closer to what the user may have entered. 39 */ 35 40 public class DerbyWrapper 36 41 { … … 474 479 } 475 480 476 public boolean addUser(String username, String password, String groups, String accountstatus, String comment, String email)481 public boolean addUser(String username, String password, String expandedGroups, String accountstatus, String comment, String email) 477 482 { 478 483 try … … 482 487 state.execute(sql_insert_user); 483 488 484 String[] groupArray = groups.split(",");489 String[] groupArray = expandedGroups.split(","); 485 490 for (String g : groupArray) 486 491 { … … 719 724 } 720 725 721 public String modifyUserInfo(String username, String new_password, String groups, String accountstatus, String comment, String email)726 public String modifyUserInfo(String username, String new_password, String expandedGroups, String accountstatus, String comment, String email) 722 727 { 723 728 try … … 750 755 state.execute(sql_delete_groups); 751 756 752 String[] groupsArray = groups.split(",");757 String[] groupsArray = expandedGroups.split(","); 753 758 for (String g : groupsArray) 754 759 { -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/ModifyUsersDB.java
r35287 r35298 121 121 else 122 122 { // add new user 123 groups = UserTermInfo.expandGroups(groups); 123 124 //System.err.println("**** Trying to add user: "); 124 125 //System.err.println("**** " + username + " " + password + " " + groups + " " + accountstatus + " " + comment + " " + email); … … 138 139 if (groups.equals("")) 139 140 { 140 // groups should be origGroups and not expandedGroups 141 // As we want to store the groups in DB as entered 142 // and not as programmatically expanded. 143 groups = user.getOrigGroups(); 141 // groups should be expandedGroups because we no longer store the groups in userDB 142 // as user-entered or compacted, but as programmatically expanded. 143 // This allows HttpServletRequest.isUserInRole() to now automatically retrieve the 144 // expandedGroups list of a user to check collectionConfig.xml security elements against. 145 146 groups = user.getExpandedGroups(); 147 } else { 148 groups = UserTermInfo.expandGroups(groups); // ensure groups are stored expanded in userDB 144 149 } 145 150 if (accountstatus.equals("")) -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/UserQueryResult.java
r35286 r35298 37 37 } 38 38 39 public void addUserTerm(String username, String password, String groups, String accountstatus, String comment, String email)39 public void addUserTerm(String username, String password, String expandedGroups, String accountstatus, String comment, String email) 40 40 { 41 UserTermInfo ui = new UserTermInfo(username, password, groups,41 UserTermInfo ui = new UserTermInfo(username, password, expandedGroups, 42 42 accountstatus, comment, email); 43 43 users.add(ui); -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/UserTermInfo.java
r35287 r35298 27 27 private String username; 28 28 private String password; 29 private String origGroups; 30 private String expandedGroups = null;29 private String origGroups = null; // TODO: rename to compactedGroups and get-method, and update method calls accordingly 30 private String expandedGroups; 31 31 private String accountstatus; 32 32 private String comment; 33 33 private String email; 34 34 35 public UserTermInfo(String username, String password, String groups, 35 // This constructor is called to instantiate a UserTermInfo object from entries in the userDB 36 // which now stores expandedGroups instead of the user-entered origGroups 37 // Use the other constructor if you know the user-entered groups 38 public UserTermInfo(String username, String password, String expandedGroups, 36 39 String accountStatus, String comment, String email) { 37 40 this.username = username; 38 41 this.password = password; 39 this.origGroups = groups; 40 //this.expandedGroups = UserTermInfo.expandGroups(this.origGroups); // Will do lazy evaluation 42 43 44 this.expandedGroups = expandedGroups; 45 this.origGroups = UserTermInfo.compactGroups(this.expandedGroups); // alternative: don't set here and do lazy evaluation when getOrigGroups() is called 41 46 this.accountstatus = accountStatus; 42 47 this.comment = comment; 43 48 this.email = email; 44 49 } 50 51 52 // Not used, for completion's sake: 53 // If you only have user-entered groups at hand, pass in null or "" for expandedGroups 54 // to create a UserTermInfo object, which will work out the expandedGroups. 55 /* 56 public UserTermInfo(String username, String password, String userEnteredGroups, String expandedGroups, 57 String accountStatus, String comment, String email) { 58 this.username = username; 59 this.password = password; 60 61 this.origGroups = (userEnteredGroups == null) ? "" : userEnteredGroups; 62 if(expandedGroups == null || expandedGroups.equals("")) { 63 this.expandedGroups = UserTermInfo.expandGroups(this.origGroups); 64 } 65 this.accountstatus = accountStatus; 66 this.comment = comment; 67 this.email = email; 68 } 69 */ 45 70 46 71 public String toString() … … 67 92 public String getOrigGroups() { 68 93 return origGroups; 69 } 70 71 public String getExpandedGroups() { 72 //return expandedGroups; 73 //return UserTermInfo.expandGroups(this.origGroups); // not storing, evaluating on demand 74 94 //return UserTermInfo.compactGroups(this.expandedGroups); // not storing, evaluating on demand 95 75 96 // lazy evaluation: getExpandedGroups() doesn't get called on every enquiry about 76 97 // a UserTermInfo struct. It only gets called on authenticated-ping system-action … … 79 100 // don't pre-calculate and store the expanded groups. 80 101 // Is it meaningful to store this at all Ever or better to always evaluate on demand? 81 if(expandedGroups == null) { 82 expandedGroups = UserTermInfo.expandGroups(this.origGroups); 83 } 102 103 } 104 105 public String getExpandedGroups() { 84 106 return expandedGroups; 107 //return UserTermInfo.expandGroups(this.origGroups); // not storing, evaluating on demand 108 109 // lazy evaluation: getExpandedGroups() doesn't get called on every enquiry about 110 // a UserTermInfo struct. It only gets called on authenticated-ping system-action 111 // (including via ServletRealmCheck being run from run from commandline or gliserver.pl) 112 // So for a whole list of users and the UserTermInfo struct of each, 113 // don't pre-calculate and store the expanded groups. 114 // Is it meaningful to store this at all Ever or better to always evaluate on demand? 115 ///if(expandedGroups == null) { 116 /// expandedGroups = UserTermInfo.expandGroups(this.origGroups); 117 ///} 118 ///return expandedGroups; 85 119 } 86 120 … … 101 135 } 102 136 137 /** 138 * The user may have entered groups of the form "nz.ac.waikato.toto, nz.ac.waikato.cs.pinky, admin" 139 * This would have got stored in the userDB in expanded form as: "admin, nz, nz.ac, nz.ac.waikato, nz.ac.waikato.cs, nz.ac.waikato.cs.pinky, nz.ac.waikato.toto" 140 * This method should return the user entered form again, or the most compact form at any rate. So duplicates removed and in natural (alphabetic) ordering. 141 * @param groups: given possibly expanded_groups, this method contracts them back to what the user would have entered for groups 142 * @return the user-entered form for groups 143 * Tested: 144 * String groups = "administrator,all-collections-editor,nz,nz.ac,nz.ac.waikato,nz.ac.waikato.cs.pinkies, nz.ac.waikato.totos.toto, nz.ac.waikato.cs.pinkies.pinky, personal-collections-editor"; 145 * and shuffled: 146 * String groups = "nz,nz.ac,nz.ac.waikato,administrator,nz.ac.waikato.cs.pinkies, nz.ac.waikato.totos.toto, nz.ac.waikato.cs.pinkies.pinky, personal-collections-editor,all-collections-editor"; 147 * Result: administrator,all-collections-editor,nz.ac.waikato.cs.pinkies.pinky,nz.ac.waikato.totos.toto,personal-collections-editor: 148 */ 149 public static String compactGroups(String groups) { 150 if(groups.indexOf('.') == -1) { 151 return groups; 152 } 153 else if(groups.equals("")) { // can return quickly if empty string 154 return groups; 155 } 156 else { // groups is a non-zero comma-separated list because we've already tested there's a period mark in it somewhere 157 158 // Normalize step: make sure what's in the database has no duplicates and is in natural ordering 159 Set<String> groupSet = new TreeSet<String>(); // uses default (alphabetic/ascii) comparator 160 String[] indivGroups = groups.split("\\s*,\\s*"); // simultaneously get rid of whitespace surrounding commas 161 for(String s : indivGroups) { 162 groupSet.add(s); // will get rid of duplicate prefixes, although it "should" have been stored without duplicates 163 // But normalizing here ensures that the rest of the method always works with the correct ordering 164 } 165 166 indivGroups = new String[groupSet.size()]; 167 indivGroups = groupSet.toArray(indivGroups); // now indivGroups is in natural ordering 168 groupSet.clear(); 169 groupSet = null; 170 171 // The actual algorithm is now simple: if next group string doesn't start with current one 172 // (so current group string is not prefix of next group string), we add it to our compactGroups list 173 Set<String> compactGroups = new TreeSet<String>(); // uses default (alphabetic/ascii) comparator 174 String currGroup, nextGroup; 175 for(int i = 0; i < indivGroups.length-1; i++) { 176 currGroup = indivGroups[i]; 177 nextGroup = indivGroups[i+1]; 178 179 if(!nextGroup.startsWith(currGroup)) { 180 compactGroups.add(currGroup); 181 } 182 } 183 184 // don't forget to add in the very last group string 185 compactGroups.add(indivGroups[indivGroups.length-1]); 186 187 188 // recreate comma-separate string of groups 189 StringBuilder compactGroupList = new StringBuilder(); 190 for(String s : compactGroups) { 191 compactGroupList.append(s); 192 compactGroupList.append(','); 193 } 194 compactGroupList.deleteCharAt(compactGroupList.length()-1); // remove extraneous comma 195 196 return compactGroupList.toString(); 197 } 198 199 200 /* 201 else { 202 203 204 String[] indivGroups = groups.split("\\s*,\\s*"); // simultaneously get rid of whitespace surrounding commas 205 if(indivGroups.length == 0) { 206 return groups; 207 } 208 Set<String> compactGroups = new TreeSet<String>(); 209 String currGroup = indivGroups[indivGroups.length-1]; 210 for(int i = indivGroups.length-1; i--; i > 0) { 211 String prevGroup = indivGroups[i-1]; 212 213 int indexOfPeriod = currGroup.indexOf('.'); 214 if(indexOfPeriod == -1) { 215 compactGroups.add(currGroup); 216 currGroup = prevGroup; 217 } 218 else { 219 220 if(currGroup.startsWith(prevGroup)) { 221 compactGroups.add(currGroup); 222 if(i == 0) { 223 break; 224 } else { 225 i--; 226 currGroup = indivGroups[i]; 227 } 228 } 229 else { 230 compactGroups.add(currGroup); 231 currGroup = prevGroup; 232 } 233 } 234 } 235 } 236 */ 237 } 238 239 103 240 /** We might have groups of the form katoa.maori.(placename.)iwi-name.hapu-name.personal-name 104 241 * ("katoa" means all, we could also use "mema" meaning member for this initial position). … … 138 275 return groups; 139 276 } 277 else if(groups.equals("")) { // can return quickly if empty string 278 return groups; 279 } 140 280 else { 141 281 Set<String> allGroups = new TreeSet<String>(); … … 159 299 160 300 161 StringBuilder expandedGroupList = new StringBuilder(); //"<groups = \"");301 StringBuilder expandedGroupList = new StringBuilder(); 162 302 for(String s : allGroups) { 163 303 expandedGroupList.append(s); … … 165 305 } 166 306 expandedGroupList.deleteCharAt(expandedGroupList.length()-1); // remove extraneous comma 167 168 //expandedGroupList.append("\">");169 307 170 308 return expandedGroupList.toString(); -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/txt2usersDB.java
r35287 r35298 166 166 password = Authentication.hashPassword(password); 167 167 } // if > 8 chars, password for user being added was already encrypted (hashed-and-hexed) 168 dw.addUser(username, password, groups, accountstatus, comment, email);168 dw.addUser(username, password, UserTermInfo.expandGroups(groups), accountstatus, comment, email); 169 169 } 170 170 … … 185 185 } 186 186 187 // groups should be origGroups and not expandedGroups 188 // As we want to store the groups in DB as entered 189 // and not as programmatically expanded. 190 groups = groups.equals("") ? user.getOrigGroups() : groups; 187 // groups should be expandedGroups because we no longer store the groups in userDB 188 // as user-entered or compacted, but as programmatically expanded. 189 // This allows HttpServletRequest.isUserInRole() to now automatically retrieve the 190 // expandedGroups list of a user to check collectionConfig.xml security elements against. 191 192 groups = groups.equals("") ? user.getExpandedGroups() : UserTermInfo.expandGroups(groups); 191 193 accountstatus = accountstatus.equals("") ? user.getAccountStatus() : accountstatus; 192 194 comment = comment.equals("") ? user.getComment() : comment;
Note:
See TracChangeset
for help on using the changeset viewer.