Java tutorial
// // Copyright (C) 2010-2016 Roger Rene Kommer & Micromata GmbH // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package de.micromata.genome.gwiki.umgmt; import java.io.Serializable; import java.security.MessageDigest; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; import de.micromata.genome.gdbfs.FileNameUtils; import de.micromata.genome.gwiki.auth.GWikiSimpleUser; import de.micromata.genome.gwiki.auth.GWikiSimpleUserAuthorization; import de.micromata.genome.gwiki.auth.PasswordUtils; import de.micromata.genome.gwiki.model.AuthorizationFailedException; import de.micromata.genome.gwiki.model.GWikiAuthorizationExt; import de.micromata.genome.gwiki.model.GWikiAuthorizationRights; import de.micromata.genome.gwiki.model.GWikiElement; import de.micromata.genome.gwiki.model.GWikiElementInfo; import de.micromata.genome.gwiki.model.GWikiPropKeys; import de.micromata.genome.gwiki.model.GWikiProps; import de.micromata.genome.gwiki.model.GWikiPropsArtefakt; import de.micromata.genome.gwiki.model.GWikiRight; import de.micromata.genome.gwiki.model.GWikiRoleConfig; import de.micromata.genome.gwiki.model.GWikiWebUtils; import de.micromata.genome.gwiki.model.logging.GWikiLogCategory; import de.micromata.genome.gwiki.model.matcher.GWikiPageIdMatcher; import de.micromata.genome.gwiki.page.GWikiContext; import de.micromata.genome.gwiki.plugin.GWikiPlugin; import de.micromata.genome.logging.GLog; import de.micromata.genome.util.matcher.BooleanListMatcher; import de.micromata.genome.util.matcher.BooleanListRulesFactory; import de.micromata.genome.util.matcher.EqualsMatcher; import de.micromata.genome.util.matcher.Matcher; import de.micromata.genome.util.matcher.TreeStateMatcher; import de.micromata.genome.util.matcher.string.StartWithMatcher; import de.micromata.genome.util.runtime.CallableX; import de.micromata.genome.util.types.Converter; /** * User authorization. Elements are store inside admin/users/ * * @author Roger Rene Kommer (r.kommer@micromata.de) * */ public class GWikiUserAuthorization extends GWikiSimpleUserAuthorization implements GWikiAuthorizationExt { /** * is the current user your user * * @param wikiContext * @return */ public static boolean isOwnUser(GWikiContext wikiContext) { GWikiSimpleUser user = GWikiUserServeElementFilterEvent.getUser(); if (user == null || user.isAnon() == true) { return false; } return true; } public static String encryptLecacy(String plaintext) { try { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(plaintext.getBytes("UTF-8")); byte raw[] = md.digest(); String hash = Converter.encodeBase64(raw); return hash; } catch (Exception ex) { /** * @logging * @reason Beim asymetrischen verschluesseln ist ein Fehler aufgetreten. * @action Ueberpruefen der Java-Installation */ throw new RuntimeException(ex); } } public static String encrypt(String plaintext) { return PasswordUtils.createSaltedPassword(plaintext); } @Override public boolean needAuthorization(GWikiContext ctx) { GWikiSimpleUser su = getSingleUser(ctx); if (su == null) { return true; } return su.isAnon(); } private Matcher<String> replaceMatcherRules(GWikiRoleConfig rc, Matcher<String> m) { if (m instanceof EqualsMatcher) { EqualsMatcher<String> em = (EqualsMatcher<String>) m; GWikiRight role = rc.getRoles().get(em.getOther()); if (role != null && role.getDefinitionRule() != null) { return role.getDefinitionRule(); } return m; } if (m instanceof BooleanListMatcher) { BooleanListMatcher<String> bm = (BooleanListMatcher<String>) m; List<Matcher<String>> ml = bm.getMatcherList(); for (int i = 0; i < ml.size(); ++i) { ml.set(i, replaceMatcherRules(rc, ml.get(i))); } return m; } if (m instanceof TreeStateMatcher) { TreeStateMatcher<String> tm = (TreeStateMatcher<String>) m; tm.setNested(replaceMatcherRules(rc, tm.getNested())); } return m; } public GWikiSimpleUser createSimpleUser(GWikiElement el, GWikiContext ctx, GWikiProps props) { String userId = GWikiContext.getNamePartFromPageId(el.getElementInfo().getId()); String rr = props.getStringValue(USER_PROP_RIGHTSRULE); GWikiSimpleUser user = new GWikiSimpleUser(userId, props.getStringValue(USER_PROP_PASSWORD), props.getStringValue(USER_PROP_EMAIL), rr); user.setDeactivated(props.getBooleanValue(USER_PROP_DEACTIVATED)); user.setProps(props.getMap()); GWikiRoleConfig rc = getRoleConfig(ctx); if (rc == null) { return user; } user.setRightsMatcher(replaceMatcherRules(rc, user.getRightsMatcher())); return user; } @Override public boolean createUser(GWikiContext wikiContext, String userName, GWikiProps props) { if (hasUser(wikiContext, userName) == true) { return false; } String id = "admin/user/" + userName; GWikiElement userEl = GWikiWebUtils.createNewElement(wikiContext, id, "admin/templates/intern/WikiUserMetaTemplate", id); GWikiProps settings = userEl.getElementInfo().getProps(); settings.setStringValue(GWikiPropKeys.AUTH_EDIT, GWikiAuthorizationRights.GWIKI_PRIVATE.name()); settings.setStringValue(GWikiPropKeys.AUTH_VIEW, GWikiAuthorizationRights.GWIKI_PRIVATE.name()); settings.setStringValue(GWikiPropKeys.CREATEDBY, userName); GWikiPropsArtefakt us = (GWikiPropsArtefakt) userEl.getMainPart(); us.setCompiledObject(props); wikiContext.getWikiWeb().saveElement(wikiContext, userEl, false); return true; } @Override public boolean hasUser(GWikiContext wikiContext, String userName) { if (StringUtils.isBlank(userName) == true) { return false; } String id = "admin/user/" + userName; GWikiElementInfo ei = wikiContext.getWikiWeb().findElementInfo(id); return ei != null; } protected GWikiElement findUserElement(GWikiContext ctx, String user) { if (ctx.getWikiWeb() == null) { return null; } String id = "admin/user/" + user; GWikiElement el = ctx.getWikiWeb().findElement(id); return el; } public GWikiSimpleUser findFallbackUser(GWikiContext ctx, String user) { String wdun = ctx.getWikiWeb().getDaoContext().getWebDavUserName(); if (StringUtils.equals(wdun, user) == false) { return null; } GWikiSimpleUser wdu = new GWikiSimpleUser(wdun, ctx.getWikiWeb().getDaoContext().getWebDavPasswordHash(), "gwiki-noreply@micromata.de", "+*"); return wdu; } @Override public GWikiSimpleUser findUser(GWikiContext ctx, String user) { if (StringUtils.isBlank(user) == true) { return null; } GWikiElement el = findUserElement(ctx, user); if (el == null) { return null; } Serializable ser = el.getMainPart().getCompiledObject(); GWikiProps props = (GWikiProps) ser; GWikiSimpleUser suser = createSimpleUser(el, ctx, props); if (suser != null) { return suser; } return null; // return findFallbackUser(ctx, user); } @Override public <T> T runAsUser(String user, GWikiContext wikiContext, CallableX<T, RuntimeException> callback) { GWikiSimpleUser pu = GWikiUserServeElementFilterEvent.getUser(); GWikiSimpleUser su = findUser(wikiContext, user); if (su == null) { throw new AuthorizationFailedException("User doesn't exits: " + user); } try { GWikiUserServeElementFilterEvent.setUser(su); return callback.call(); } finally { GWikiUserServeElementFilterEvent.setUser(pu); } } @Override public boolean login(GWikiContext ctx, String user, String password) { GWikiSimpleUser su = findUser(ctx, user); if (su == null) { return false; } if (su.isDeactivated() == true) { GLog.note(GWikiLogCategory.Wiki, "Deactivated user login attempt: " + user); return false; } if (PasswordUtils.checkSaltedPassword(password, su.getPassword()) == false) { String penc = encryptLecacy(password); if (StringUtils.equals(su.getPassword(), penc) == false) { return false; } } return afterLogin(ctx, su); } @Override public void setUserProp(GWikiContext ctx, String key, String value, UserPropStorage storage) { GWikiSimpleUser su = getSingleUser(ctx); switch (storage) { case Client: setUserPropInCookie(ctx, key, value); break; case Server: GWikiElement el = findUserElement(ctx, su.getUser()); if (el == null) { return; } Serializable ser = el.getMainPart().getCompiledObject(); GWikiProps props = (GWikiProps) ser; props.setStringValue(key, value); ctx.getWikiWeb().saveElement(ctx, el, false); break; case Transient: if (su != null) { su.getProps().put(key, value); } break; } } public static GWikiRoleConfig getRoleConfig(GWikiContext wikiContext) { GWikiElement el = wikiContext.getWikiWeb().findElement("admin/config/GWikiUserRolesConfig"); if (el == null) { return null; } GWikiRoleConfig rc = (GWikiRoleConfig) el.getMainPart().getCompiledObject(); for (GWikiPlugin plugin : wikiContext.getWikiWeb().getDaoContext().getPluginRepository() .getActivePlugins()) { if (plugin.getDescriptor().getRights() == null || plugin.getDescriptor().getRights().isEmpty() == true) { continue; } for (GWikiRight r : plugin.getDescriptor().getRights()) { if (rc.getRoles().containsKey(r.getName()) == true) { continue; } rc.addRight(r); } } return rc; } protected void getConfigSystemRights(GWikiContext wikiContext, Map<String, GWikiRight> rights) { GWikiRoleConfig rc = getRoleConfig(wikiContext); if (rc == null) { return; } rights.putAll(rc.getRoles()); } public void getSystemRights(GWikiContext wikiContext, Map<String, GWikiRight> rights) { for (GWikiAuthorizationRights ar : GWikiAuthorizationRights.values()) { rights.put(ar.name(), new GWikiRight(ar.name(), GWikiRight.RIGHT_CAT_SYSTEM_RIGHT, null)); } getConfigSystemRights(wikiContext, rights); } public void getPageRights(GWikiContext wikiContext, SortedMap<String, GWikiRight> rights) { for (GWikiElementInfo ei : wikiContext.getWikiWeb().getElementInfos()) { String r = ei.getProps().getStringValue(GWikiPropKeys.AUTH_EDIT); if (StringUtils.isNotBlank(r) == true) { if (rights.containsKey(r) == false) { rights.put(r, new GWikiRight(r, GWikiRight.RIGHT_CAT_PAGE_RIGHT, null)); } } r = ei.getProps().getStringValue(GWikiPropKeys.AUTH_VIEW); if (StringUtils.isNotBlank(r) == true) { if (rights.containsKey(r) == false) { rights.put(r, new GWikiRight(r, GWikiRight.RIGHT_CAT_PAGE_RIGHT, null)); } } } } public void getUsersRights(GWikiContext wikiContext, SortedMap<String, GWikiRight> rights) { List<GWikiElementInfo> users = wikiContext.getElementFinder() .getPageInfos(new GWikiPageIdMatcher(wikiContext, new StartWithMatcher<String>("admin/user/"))); for (GWikiElementInfo el : users) { GWikiSimpleUser user = findUser(wikiContext, FileNameUtils.getNamePart(el.getId())); String rules = user.getRightsMatcherRule(); List<String> roles = getRoleListFromUserRoleString(rules); for (String r : roles) { if (rights.containsKey(r) == false) { rights.put(r, new GWikiRight(r, GWikiRight.RIGHT_CAT_OTHER_RIGHT, "")); } } } } @Override public SortedMap<String, GWikiRight> getSystemRights(GWikiContext wikiContext) { SortedMap<String, GWikiRight> ret = new TreeMap<String, GWikiRight>(); getSystemRights(wikiContext, ret); getPageRights(wikiContext, ret); getUsersRights(wikiContext, ret); return ret; } public GWikiRight getRightFromString(String rs, Map<String, GWikiRight> systemRights) { GWikiRight r = systemRights.get(rs); if (r != null) { return r; } return new GWikiRight(rs, GWikiRight.RIGHT_CAT_OTHER_RIGHT, ""); } public boolean collectRights(Matcher<String> m, Map<String, GWikiRight> systemRights, SortedMap<String, GWikiRight> ret) { if (m instanceof EqualsMatcher) { EqualsMatcher<String> em = (EqualsMatcher<String>) m; ret.put(em.getOther(), getRightFromString(em.getOther(), systemRights)); return true; } if (m instanceof BooleanListMatcher) { BooleanListMatcher<String> bm = (BooleanListMatcher<String>) m; List<Matcher<String>> ml = bm.getMatcherList(); for (int i = 0; i < ml.size(); ++i) { if (collectRights(ml.get(i), systemRights, ret) == false) { return false; } } return true; } if (m instanceof TreeStateMatcher) { TreeStateMatcher<String> tm = (TreeStateMatcher<String>) m; if (tm.isValue() == false) { return false; } return collectRights(tm.getNested(), systemRights, ret); } return false; } List<String> getRoleListFromUserRoleString(String roleString) { if (StringUtils.isEmpty(roleString)) { return Collections.emptyList(); } List<String> roles = Converter.parseStringTokens(roleString, ",", false); for (int i = 0; i < roles.size(); ++i) { String role = roles.get(i); if (role.startsWith("+") == true) { role = role.substring(1); roles.set(i, role); } } return roles; } @Override public SortedMap<String, GWikiRight> getUserRight(GWikiContext wikiContext, Map<String, GWikiRight> systemRights, String roleString) { Matcher<String> rightsMatcher = new BooleanListRulesFactory<String>().createMatcher(roleString); GWikiRoleConfig rc = getRoleConfig(wikiContext); if (rc != null) { rightsMatcher = replaceMatcherRules(rc, rightsMatcher); } SortedMap<String, GWikiRight> ret = new TreeMap<String, GWikiRight>(); if (collectRights(rightsMatcher, systemRights, ret) == true) { return ret; } ret = new TreeMap<String, GWikiRight>(); List<String> roles = getRoleListFromUserRoleString(roleString); for (String role : roles) { if (systemRights.containsKey(role) == true) { ret.put(role, systemRights.get(role)); } else { ret.put(role, new GWikiRight(role, GWikiRight.RIGHT_CAT_OTHER_RIGHT, "")); } } // props.getStringList(key) return ret; } }