Search in sources :

Example 1 with XWikiRightNotFoundException

use of com.xpn.xwiki.user.api.XWikiRightNotFoundException in project xwiki-platform by xwiki.

the class XWikiRightServiceImpl method isSuperUser.

private boolean isSuperUser(String accessLevel, String name, String resourceKey, boolean user, XWikiDocument xwikidoc, int maxRecursiveSpaceChecks, XWikiContext context) throws XWikiException {
    boolean allow;
    // Verify XWiki super user
    try {
        allow = checkRight(name, xwikidoc, "admin", user, true, true, context);
        if (allow) {
            logAllow(name, resourceKey, accessLevel, "admin level");
            return true;
        }
    } catch (XWikiRightNotFoundException e) {
    }
    XWikiDocument documentName = new XWikiDocument();
    documentName.setFullName(resourceKey);
    // Verify Web super user
    String space = documentName.getSpace();
    ArrayList<String> spacesChecked = new ArrayList<String>();
    int recursiveSpaceChecks = 0;
    while ((space != null) && (recursiveSpaceChecks <= maxRecursiveSpaceChecks)) {
        // Add one to the recursive space checks
        recursiveSpaceChecks++;
        // add to list of spaces already checked
        spacesChecked.add(space);
        XWikiDocument webdoc = context.getWiki().getDocument(space, "WebPreferences", context);
        if (!webdoc.isNew()) {
            try {
                allow = checkRight(name, webdoc, "admin", user, true, true, context);
                if (allow) {
                    logAllow(name, resourceKey, accessLevel, "web admin level");
                    return true;
                }
            } catch (XWikiRightNotFoundException e) {
            }
            // find the parent web to check rights on it
            space = webdoc.getStringValue("XWiki.XWikiPreferences", "parent");
            if ((space == null) || (space.trim().equals("")) || spacesChecked.contains(space)) {
                // no parent space or space already checked (recursive loop). let's finish the
                // loop
                space = null;
            }
        } else {
            space = null;
        }
    }
    return false;
}
Also used : XWikiDocument(com.xpn.xwiki.doc.XWikiDocument) ArrayList(java.util.ArrayList) XWikiRightNotFoundException(com.xpn.xwiki.user.api.XWikiRightNotFoundException)

Example 2 with XWikiRightNotFoundException

use of com.xpn.xwiki.user.api.XWikiRightNotFoundException in project xwiki-platform by xwiki.

the class XWikiRightServiceImpl method checkRight.

public boolean checkRight(String userOrGroupName, XWikiDocument doc, String accessLevel, boolean user, boolean allow, boolean global, XWikiContext context) throws XWikiRightNotFoundException, XWikiException {
    if (!global && ("admin".equals(accessLevel))) {
        // Admin rights do not exist at document level.
        throw new XWikiRightNotFoundException();
    }
    EntityReference rightClassReference = global ? GLOBALRIGHTCLASS_REFERENCE : RIGHTCLASS_REFERENCE;
    String fieldName = user ? "users" : "groups";
    boolean found = false;
    // Here entity is either a user or a group
    DocumentReference userOrGroupDocumentReference = this.currentMixedDocumentReferenceResolver.resolve(userOrGroupName);
    String prefixedFullName = this.entityReferenceSerializer.serialize(userOrGroupDocumentReference);
    String shortname = userOrGroupName;
    int i0 = userOrGroupName.indexOf(":");
    if (i0 != -1) {
        shortname = userOrGroupName.substring(i0 + 1);
    }
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Checking right: [{}], [{}], [{}], [{}], [{}], [{}]", userOrGroupName, doc.getFullName(), accessLevel, user, allow, global);
    }
    List<BaseObject> rightObjects = doc.getXObjects(rightClassReference);
    if (rightObjects != null) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Checking objects [{}]", rightObjects.size());
        }
        for (int i = 0; i < rightObjects.size(); i++) {
            LOGGER.debug("Checking object [{}]", i);
            BaseObject bobj = rightObjects.get(i);
            if (bobj == null) {
                LOGGER.debug("Bypass object [{}]", i);
                continue;
            }
            String users = bobj.getStringValue(fieldName);
            String levels = bobj.getStringValue("levels");
            boolean allowdeny = (bobj.getIntValue("allow") == 1);
            if (allowdeny == allow) {
                LOGGER.debug("Checking match: [{}] in [{}]", accessLevel, levels);
                String[] levelsarray = StringUtils.split(levels, " ,|");
                if (ArrayUtils.contains(levelsarray, accessLevel)) {
                    LOGGER.debug("Found a right for [{}]", allow);
                    found = true;
                    LOGGER.debug("Checking match: [{}] in [{}]", userOrGroupName, users);
                    String[] userarray = GroupsClass.getListFromString(users).toArray(new String[0]);
                    for (int ii = 0; ii < userarray.length; ii++) {
                        String value = userarray[ii];
                        if (value.indexOf(".") == -1) {
                            userarray[ii] = "XWiki." + value;
                        }
                    }
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Checking match: [{}] in [{}]", userOrGroupName, StringUtils.join(userarray, ","));
                    }
                    // name is requested
                    if (doc.getWikiName().equals(userOrGroupDocumentReference.getWikiReference().getName())) {
                        if (ArrayUtils.contains(userarray, shortname)) {
                            LOGGER.debug("Found matching right in [{}] for [{}]", users, shortname);
                            return true;
                        }
                        // We should also allow to skip "XWiki." from the usernames and group
                        // lists
                        String veryshortname = shortname.substring(shortname.indexOf(".") + 1);
                        if (ArrayUtils.contains(userarray, veryshortname)) {
                            LOGGER.debug("Found matching right in [{}] for [{}]", users, shortname);
                            return true;
                        }
                    }
                    if ((context.getWikiId() != null) && (ArrayUtils.contains(userarray, userOrGroupName))) {
                        LOGGER.debug("Found matching right in [{}] for [{}]", users, userOrGroupName);
                        return true;
                    }
                    LOGGER.debug("Failed match: [{}] in [{}]", userOrGroupName, users);
                }
            } else {
                LOGGER.debug("Bypass object [{}] because wrong allow/deny", i);
            }
        }
    }
    LOGGER.debug("Searching for matching rights at group level");
    // Didn't found right at this level.. Let's go to group level
    Map<String, Collection<String>> grouplistcache = (Map<String, Collection<String>>) context.get("grouplist");
    if (grouplistcache == null) {
        grouplistcache = new HashMap<String, Collection<String>>();
        context.put("grouplist", grouplistcache);
    }
    Collection<String> grouplist = new HashSet<String>();
    // Get member groups from document's wiki
    addMemberGroups(doc.getWikiName(), prefixedFullName, userOrGroupDocumentReference, grouplist, context);
    // Get member groups from member's wiki
    if (!context.getWikiId().equalsIgnoreCase(userOrGroupDocumentReference.getWikiReference().getName())) {
        addMemberGroups(userOrGroupDocumentReference.getWikiReference().getName(), prefixedFullName, userOrGroupDocumentReference, grouplist, context);
    }
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Searching for matching rights for [{}] groups: [{}]", grouplist.size(), grouplist);
    }
    for (String group : grouplist) {
        try {
            // We need to construct the full group name to make sure the groups are
            // handled separately
            boolean result = checkRight(group, doc, accessLevel, false, allow, global, context);
            if (result) {
                return true;
            }
        } catch (XWikiRightNotFoundException e) {
        } catch (Exception e) {
            LOGGER.error("Failed to check right [{}] for group [{}] on document [ΒΆ}]", accessLevel, group, doc.getPrefixedFullName(), e);
        }
    }
    LOGGER.debug("Finished searching for rights for [{}]: [{}]", userOrGroupName, found);
    if (found) {
        return false;
    } else {
        throw new XWikiRightNotFoundException();
    }
}
Also used : XWikiException(com.xpn.xwiki.XWikiException) XWikiRightNotFoundException(com.xpn.xwiki.user.api.XWikiRightNotFoundException) BaseObject(com.xpn.xwiki.objects.BaseObject) EntityReference(org.xwiki.model.reference.EntityReference) Collection(java.util.Collection) HashMap(java.util.HashMap) Map(java.util.Map) XWikiRightNotFoundException(com.xpn.xwiki.user.api.XWikiRightNotFoundException) DocumentReference(org.xwiki.model.reference.DocumentReference) HashSet(java.util.HashSet)

Example 3 with XWikiRightNotFoundException

use of com.xpn.xwiki.user.api.XWikiRightNotFoundException in project xwiki-platform by xwiki.

the class XWikiRightServiceImpl method hasAccessLevel.

public boolean hasAccessLevel(String accessLevel, String userOrGroupName, String entityReference, boolean user, XWikiContext context) throws XWikiException {
    LOGGER.debug("hasAccessLevel for [{}], [{}], [{}]", accessLevel, userOrGroupName, entityReference);
    DocumentReference userOrGroupNameReference = this.currentMixedDocumentReferenceResolver.resolve(userOrGroupName);
    if (!userOrGroupNameReference.getName().equals(XWikiRightService.GUEST_USER) && context.getWikiId() != null) {
        // Make sure to have the prefixed full name of the user or group
        userOrGroupName = this.entityReferenceSerializer.serialize(this.currentMixedDocumentReferenceResolver.resolve(userOrGroupName, DEFAULTUSERSPACE));
        // Make sure to have the prefixed full name of the resource
        entityReference = this.entityReferenceSerializer.serialize(this.currentMixedDocumentReferenceResolver.resolve(entityReference));
    }
    boolean deny = false;
    boolean allow = false;
    boolean allow_found = false;
    boolean deny_found = false;
    boolean isReadOnly = context.getWiki().isReadOnly();
    String database = context.getWikiId();
    XWikiDocument currentdoc = null;
    if (isReadOnly) {
        if ("edit".equals(accessLevel) || "delete".equals(accessLevel) || "undelete".equals(accessLevel) || "comment".equals(accessLevel) || "register".equals(accessLevel)) {
            logDeny(userOrGroupName, entityReference, accessLevel, "server in read-only mode");
            return false;
        }
    }
    if (userOrGroupNameReference.getName().equals(XWikiRightService.GUEST_USER)) {
        if (needsAuth(accessLevel, context)) {
            return false;
        }
    }
    // Fast return for delete right: allow the creator to delete the document
    if (accessLevel.equals("delete") && user) {
        currentdoc = context.getWiki().getDocument(entityReference, context);
        DocumentReference creator = currentdoc.getCreatorReference();
        if (ObjectUtils.equals(userOrGroupNameReference, creator)) {
            logAllow(userOrGroupName, entityReference, accessLevel, "delete right from document ownership");
            return true;
        }
    }
    allow = isSuperAdminOrProgramming(userOrGroupName, entityReference, accessLevel, user, context);
    if ((allow == true) || (accessLevel.equals("programming"))) {
        return allow;
    }
    try {
        currentdoc = currentdoc == null ? context.getWiki().getDocument(entityReference, context) : currentdoc;
        DocumentReference docReference = currentdoc.getDocumentReference();
        if (accessLevel.equals("edit") && (docReference.getName().equals("WebPreferences") || (docReference.getLastSpaceReference().getName().equals("XWiki") && docReference.getName().equals("XWikiPreferences")))) {
            // Since edit rights on these documents would be sufficient for a user to elevate himself to
            // admin or even programmer, we will instead check for admin access on these documents.
            // See https://jira.xwiki.org/browse/XWIKI-6987 and https://jira.xwiki.org/browse/XWIKI-2184.
            accessLevel = "admin";
        }
        // We need to make sure we are in the context of the document which rights is being checked
        context.setWikiId(currentdoc.getDatabase());
        // Verify Wiki Owner
        String wikiOwner = context.getWiki().getWikiOwner(currentdoc.getDatabase(), context);
        if (wikiOwner != null) {
            if (wikiOwner.equals(userOrGroupName)) {
                logAllow(userOrGroupName, entityReference, accessLevel, "admin level from wiki ownership");
                return true;
            }
        }
        XWikiDocument entityWikiPreferences = context.getWiki().getDocument(XWIKIPREFERENCES_REFERENCE, context);
        // Verify XWiki register right
        if (accessLevel.equals("register")) {
            try {
                allow = checkRight(userOrGroupName, entityWikiPreferences, "register", user, true, true, context);
                if (allow) {
                    logAllow(userOrGroupName, entityReference, accessLevel, "register level");
                    return true;
                } else {
                    logDeny(userOrGroupName, entityReference, accessLevel, "register level");
                    return false;
                }
            } catch (XWikiRightNotFoundException e) {
                try {
                    deny = checkRight(userOrGroupName, entityWikiPreferences, "register", user, false, true, context);
                    if (deny) {
                        return false;
                    }
                } catch (XWikiRightNotFoundException e1) {
                }
            }
            logAllow(userOrGroupName, entityReference, accessLevel, "register level (no right found)");
            return true;
        }
        int maxRecursiveSpaceChecks = context.getWiki().getMaxRecursiveSpaceChecks(context);
        boolean isSuperUser = isSuperUser(accessLevel, userOrGroupName, entityReference, user, entityWikiPreferences, maxRecursiveSpaceChecks, context);
        if (isSuperUser) {
            logAllow(userOrGroupName, entityReference, accessLevel, "admin level");
            return true;
        }
        // check has deny rights
        if (hasDenyRights()) {
            // First check if this document is denied to the specific user
            entityReference = Util.getName(entityReference, context);
            try {
                currentdoc = currentdoc == null ? context.getWiki().getDocument(entityReference, context) : currentdoc;
                deny = checkRight(userOrGroupName, currentdoc, accessLevel, user, false, false, context);
                deny_found = true;
                if (deny) {
                    logDeny(userOrGroupName, entityReference, accessLevel, "document level");
                    return false;
                }
            } catch (XWikiRightNotFoundException e) {
            }
        }
        try {
            currentdoc = currentdoc == null ? context.getWiki().getDocument(entityReference, context) : currentdoc;
            allow = checkRight(userOrGroupName, currentdoc, accessLevel, user, true, false, context);
            allow_found = true;
            if (allow) {
                logAllow(userOrGroupName, entityReference, accessLevel, "document level");
                return true;
            }
        } catch (XWikiRightNotFoundException e) {
        }
        // Check if this document is denied/allowed
        // through the space WebPreferences Global Rights
        String space = currentdoc.getSpace();
        ArrayList<String> spacesChecked = new ArrayList<String>();
        int recursiveSpaceChecks = 0;
        while ((space != null) && (recursiveSpaceChecks <= maxRecursiveSpaceChecks)) {
            // Add one to the recursive space checks
            recursiveSpaceChecks++;
            // add to list of spaces already checked
            spacesChecked.add(space);
            XWikiDocument webdoc = context.getWiki().getDocument(space, "WebPreferences", context);
            if (!webdoc.isNew()) {
                if (hasDenyRights()) {
                    try {
                        deny = checkRight(userOrGroupName, webdoc, accessLevel, user, false, true, context);
                        deny_found = true;
                        if (deny) {
                            logDeny(userOrGroupName, entityReference, accessLevel, "web level");
                            return false;
                        }
                    } catch (XWikiRightNotFoundException e) {
                    }
                }
                // then we cannot check the web rights anymore
                if (!allow_found) {
                    try {
                        allow = checkRight(userOrGroupName, webdoc, accessLevel, user, true, true, context);
                        allow_found = true;
                        if (allow) {
                            logAllow(userOrGroupName, entityReference, accessLevel, "web level");
                            return true;
                        }
                    } catch (XWikiRightNotFoundException e) {
                    }
                }
                // find the parent web to check rights on it
                space = webdoc.getStringValue("XWiki.XWikiPreferences", "parent");
                if ((space == null) || (space.trim().equals("")) || spacesChecked.contains(space)) {
                    // no parent space or space already checked (recursive loop). let's finish
                    // the loop
                    space = null;
                }
            } else {
                // let's finish the loop
                space = null;
            }
        }
        // through the XWiki.XWikiPreferences Global Rights
        if (hasDenyRights()) {
            try {
                deny = checkRight(userOrGroupName, entityWikiPreferences, accessLevel, user, false, true, context);
                deny_found = true;
                if (deny) {
                    logDeny(userOrGroupName, entityReference, accessLevel, "xwiki level");
                    return false;
                }
            } catch (XWikiRightNotFoundException e) {
            }
        }
        // then we cannot check the web rights anymore
        if (!allow_found) {
            try {
                allow = checkRight(userOrGroupName, entityWikiPreferences, accessLevel, user, true, true, context);
                allow_found = true;
                if (allow) {
                    logAllow(userOrGroupName, entityReference, accessLevel, "xwiki level");
                    return true;
                }
            } catch (XWikiRightNotFoundException e) {
            }
        }
        // should be allowed.
        if (!allow_found) {
            // Delete must be denied by default.
            if ("delete".equals(accessLevel)) {
                if (hasAccessLevel("admin", userOrGroupName, entityReference, user, context)) {
                    logAllow(userOrGroupName, entityReference, accessLevel, "admin rights imply delete on empty wiki");
                    return true;
                }
                logDeny(userOrGroupName, entityReference, accessLevel, "global level (delete right must be explicit)");
                return false;
            } else {
                logAllow(userOrGroupName, entityReference, accessLevel, "global level (no restricting right)");
                return true;
            }
        } else {
            logDeny(userOrGroupName, entityReference, accessLevel, "global level (restricting right was found)");
            return false;
        }
    } catch (XWikiException e) {
        logDeny(userOrGroupName, entityReference, accessLevel, "global level (exception)", e);
        e.printStackTrace();
        return false;
    } finally {
        context.setWikiId(database);
    }
}
Also used : XWikiDocument(com.xpn.xwiki.doc.XWikiDocument) ArrayList(java.util.ArrayList) DocumentReference(org.xwiki.model.reference.DocumentReference) XWikiRightNotFoundException(com.xpn.xwiki.user.api.XWikiRightNotFoundException) XWikiException(com.xpn.xwiki.XWikiException)

Example 4 with XWikiRightNotFoundException

use of com.xpn.xwiki.user.api.XWikiRightNotFoundException in project xwiki-platform by xwiki.

the class XWikiRightServiceImpl method isSuperAdminOrProgramming.

private boolean isSuperAdminOrProgramming(String name, String resourceKey, String accessLevel, boolean user, XWikiContext context) throws XWikiException {
    if (name == null) {
        return false;
    }
    String database = context.getWikiId();
    boolean allow;
    if (isSuperAdmin(name)) {
        logAllow(name, resourceKey, accessLevel, "super admin level");
        return true;
    }
    try {
        // The master user and programming rights are checked in the main wiki
        context.setWikiId(context.getMainXWiki());
        XWikiDocument xwikimasterdoc = context.getWiki().getDocument(XWIKIPREFERENCES_REFERENCE, context);
        // Verify XWiki Master super user
        try {
            allow = checkRight(name, xwikimasterdoc, "admin", true, true, true, context);
            if (allow) {
                logAllow(name, resourceKey, accessLevel, "master admin level");
                return true;
            }
        } catch (XWikiRightNotFoundException e) {
        }
        // Verify XWiki programming right
        if (accessLevel.equals("programming")) {
            // Programming right can only been given if user is from main wiki
            if (!name.startsWith(context.getMainXWiki() + ":")) {
                return false;
            }
            try {
                allow = checkRight(name, xwikimasterdoc, "programming", user, true, true, context);
                if (allow) {
                    logAllow(name, resourceKey, accessLevel, "programming level");
                    return true;
                } else {
                    logDeny(name, resourceKey, accessLevel, "programming level");
                    return false;
                }
            } catch (XWikiRightNotFoundException e) {
            }
            logDeny(name, resourceKey, accessLevel, "programming level (no right found)");
            return false;
        }
    } finally {
        // The next rights are checked in the virtual wiki
        context.setWikiId(database);
    }
    return false;
}
Also used : XWikiDocument(com.xpn.xwiki.doc.XWikiDocument) XWikiRightNotFoundException(com.xpn.xwiki.user.api.XWikiRightNotFoundException)

Aggregations

XWikiRightNotFoundException (com.xpn.xwiki.user.api.XWikiRightNotFoundException)4 XWikiDocument (com.xpn.xwiki.doc.XWikiDocument)3 XWikiException (com.xpn.xwiki.XWikiException)2 ArrayList (java.util.ArrayList)2 DocumentReference (org.xwiki.model.reference.DocumentReference)2 BaseObject (com.xpn.xwiki.objects.BaseObject)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 EntityReference (org.xwiki.model.reference.EntityReference)1