Пример #1
0
var resolveImplicitRole = module.exports.resolveImplicitRole = function(ctx, resourceAlias, resourceVisibility, rolesPriority, callback) {
    var user = ctx.user();

    // Anonymous cannot interact with anything and get the lowest role if the resource visibility is set to public.
    // Otherwise, they do not get a role.
    if (!user) {
        var implicitRole = null;
        if (resourceVisibility === 'public') {
            implicitRole = rolesPriority[0];
        }
        return callback(null, implicitRole, false);

    // Check admin access
    } else if (user.isGlobalAdmin() || user.isTenantAdmin(resourceAlias)) {
        // The user is an administrator, give them the highest allowable access
        return callback(null, rolesPriority[rolesPriority.length - 1], true);
    }

    // If we aren't an explicit manager, ability to interact is based on tenant privacy boundaries
    var actorAlias = (user) ? user.tenant.alias : ctx.tenant().alias;
    var canInteract = TenantsUtil.canInteract(actorAlias, resourceAlias);

    // Check implicit member access
    if (resourceVisibility === 'public') {
        // Public resources can be seen by anyone
        return callback(null, rolesPriority[0], canInteract);
    } else if (resourceVisibility === 'loggedin' && TenantsUtil.isLoggedIn(ctx, resourceAlias)) {
        // We are from the same tenant as the "loggedin" resource, so we can view it and interact
        return callback(null, rolesPriority[0], canInteract);
    }

    return callback();
};
Пример #2
0
var _canJoin = function(ctx, group, hasRole) {
    // You cannot join a group of which you're already a member
    if (hasRole) {
        return false;

    // Anonymous users can never join a group
    } else if (!ctx.user()) {
        return false;

    // TODO: For now we only support joining a group if it's joinable property has been set to YES
    } else if (group.joinable !== AuthzConstants.joinable.YES) {
        return false;

    // By this point we know the user is logged in and that people are allowed to join the group.
    // If the user is on the same tenant as the group, he can always request to join
    } else if (ctx.user().tenant.alias === group.tenant.alias) {
        return true;

    // If the user is from another tenant, he can only join the group if the tenant permeability
    // settings allow it AND the group's visibility setting is set to public
    } else if (TenantsUtil.canInteract(ctx.user().tenant.alias, group.tenant.alias) && group.visibility === AuthzConstants.visibility.PUBLIC) {
        return true;

    // In any other case, you cannot join the group
    } else {
        return false;
    }
};
Пример #3
0
        OaeUtil.invokeIfNecessary(needsExplicitCheck, AuthzAPI.hasAnyRole, (ctx.user() && ctx.user().id), libraryId, function(err, hasAnyRole) {
            if (err) {
                return callback(err);
            } else if (hasAnyRole) {
                // If the current user has an explicit role on the library resource, they can always
                // see private items
                return callback(null, true, AuthzConstants.visibility.PRIVATE);
            } else if (implicitRole && TenantsUtil.isLoggedIn(ctx, libraryOwner.tenant.alias)) {
                // If we have implicit access and we can are logged in to the library's tenant, we
                // can see loggedin items
                return callback(null, true, AuthzConstants.visibility.LOGGEDIN);
            } else if (implicitRole) {
                // If we have implicit access but aren't authenticated to the library's tenant, we
                // can see public items
                return callback(null, true, AuthzConstants.visibility.PUBLIC);
            } else if (ctx.user() && TenantsUtil.canInteract(ctx.user().tenant.alias, libraryOwner.tenant.alias) &&
                libraryOwner.joinable === AuthzConstants.joinable.YES) {
                // One weird case is if the user is able to "join" the resource (e.g., a group),
                // then they should also be able to see its public items
                return callback(null, true, AuthzConstants.visibility.PUBLIC);
            }

            // We have covered all cases where we are able to see the resource, at this point we are
            // not allowed to see its library
            return callback(null, false);
        });
Пример #4
0
var _canView = function(ctx, group, hasRole) {
    if (group.visibility === AuthzConstants.visibility.PUBLIC) {
        return true;

    // If we have a role in the group we can always view it
    } else if (hasRole) {
        return true;

    // For the following checks, we're dealing with users who are not a member of the group

    // An anonymous user can never see a non-public group
    } else if (!ctx.user()) {
        return false;

    // A group that is joinable can always be seen by an authenticated user who belongs to a tenant that can interact. Even if it is private
    } else if (group.joinable !== AuthzConstants.joinable.NO && TenantsUtil.canInteract(ctx.tenant().alias, group.tenant.alias)) {
        return true;

    // If the group is visible to logged in users, I get access if I'm logged in
    } else if (group.visibility === AuthzConstants.visibility.LOGGEDIN && TenantsUtil.isLoggedIn(ctx, group.tenant.alias)) {
        return true;

    // If the user is admin of the group's tenant, they have access
    } else if (ctx.user().isAdmin(group.tenant.alias)) {
        return true;
    }

    // In all other cases the user can't view the group
    return false;
};
Пример #5
0
 _.each(routes, function(route) {
     var routeTenantAlias = AuthzUtil.getResourceFromId(route.resourceId).tenantAlias;
     if (TenantsUtil.canInteract(entityTenantAlias, routeTenantAlias)) {
         includedRoutes.push(route);
     } else {
         excludedRoutes.push(route);
     }
 });
Пример #6
0
    PrincipalsUtil.getPrincipals(ctx, _.keys(members), function(err, principals) {
        if (err) {
            return callback(err);
        }

        // Verify no user addition violates tenant boundaries by being added
        for (var principalId in principals) {
            var principal = principals[principalId];
            if (members[principalId] && !TenantsUtil.canInteract(principal.tenant.alias, group.tenant.alias)) {
                return callback({'code': 400, 'msg': 'External user ' + principal.id + ' cannot be added as a member of this group.'});
            }
        }

        AuthzAPI.updateRoles(group.id, members, callback);
    });
Пример #7
0
var resolveImplicitRole = module.exports.resolveImplicitRole = function(ctx, resourceId, resourceTenantAlias, resourceVisibility, rolesPriority, callback) {
    var user = ctx.user();

    // Anonymous cannot interact with anything and get the lowest role if the resource visibility is set to public.
    // Otherwise, they do not get a role.
    if (!user) {
        var implicitRole = null;
        if (resourceVisibility === AuthzConstants.visibility.PUBLIC) {
            implicitRole = rolesPriority[0];
        }
        return callback(null, implicitRole, false);

    // The user has maximum access on themself
    } else if (user.id === resourceId) {
        return callback(null, rolesPriority[rolesPriority.length - 1], true);

    // Check admin access
    } else if (user.isGlobalAdmin() || user.isTenantAdmin(resourceTenantAlias)) {
        // The user is an administrator, give them the highest allowable access
        return callback(null, rolesPriority[rolesPriority.length - 1], true);
    }

    // Determine the implicit interaction capabilities between the user and the resource
    var actorTenantAlias = (user) ? user.tenant.alias : ctx.tenant().alias;
    var canInteract = TenantsUtil.canInteract(actorTenantAlias, resourceTenantAlias);

    // Check implicit member access
    if (resourceVisibility === AuthzConstants.visibility.PUBLIC) {
        // Public resources can be seen by anyone
        return callback(null, rolesPriority[0], canInteract);
    } else if (resourceVisibility === AuthzConstants.visibility.LOGGEDIN && TenantsUtil.isLoggedIn(ctx, resourceTenantAlias)) {
        // We are from the same tenant as the "loggedin" resource, so we can view it and interact
        return callback(null, rolesPriority[0], canInteract);
    }

    return callback();
};
Пример #8
0
 var illegalPrincipalIds =  _.filter(principalIds, function(principalId) {
     var principalTenantAlias = AuthzUtil.getPrincipalFromId(principalId).tenantAlias;
     // The principalId is invalid if the violates boundaries between the actor and the principal or the resource and the principal
     return (!TenantsUtil.canInteract(actorTenantAlias, principalTenantAlias) || !TenantsUtil.canInteract(resourceTenantAlias, principalTenantAlias));
 });
Пример #9
0
var canInteract = module.exports.canInteract = function(ctx, resourceTenantAlias, principalIds, callback) {
    var actorTenantAlias = ctx.user().tenant.alias;

    // Check the tenant violations:
    //  * A direct violation between actorTenantAlias and resourceTenantAlias
    if (!TenantsUtil.canInteract(actorTenantAlias, resourceTenantAlias)) {
        return callback(null, false);
    }

    //  * A direct violation between actorTenantAlias and principalIds[i].tenant
    var illegalPrincipalIds =  _.filter(principalIds, function(principalId) {
        var principalTenantAlias = AuthzUtil.getPrincipalFromId(principalId).tenantAlias;
        // The principalId is invalid if the violates boundaries between the actor and the principal or the resource and the principal
        return (!TenantsUtil.canInteract(actorTenantAlias, principalTenantAlias) || !TenantsUtil.canInteract(resourceTenantAlias, principalTenantAlias));
    });
    if (illegalPrincipalIds.length > 0) {
        return callback(null, false, illegalPrincipalIds);
    }


    // Now check if there are any access violations between the actor and a principal
    PrincipalsUtil.getPrincipals(ctx, principalIds, function(err, principalObjects) {
        if (err) {
            return callback(err);
        }

        var illegalPrincipalIds = [];
        var canInteract = true;

        /*!
         * Checks if the current user can interact with al the
         * principals in an array (recursively).
         *
         * @param  {Principal[]}  The array of principals to check. Will be empty when done.
         */
        var checkPrincipal = function(principals) {
            if (principals.length === 0) {
                // All the principals have been checked.
                // Only fill in the illegalPrincipalIds parameter if there are actually any illegal ones.
                return callback(null, canInteract, (illegalPrincipalIds.length > 0) ? illegalPrincipalIds : null);
            }

            var principal = principals.pop();

            // If the target-principal is a user we need to check tenant permeability and user visibility settings.
            // The resolveImplicitRole function will take care of that.
            if (PrincipalsUtil.isUser(principal.id)) {
                resolveImplicitRole(ctx, principal.tenant.alias, principal.visibility, ['viewer', 'manager'], function(err, implicitRole, canInteractWithUser) {
                    if (err) {
                        return callback(err);
                    }

                    if (!canInteractWithUser) {
                        canInteract = false;
                        illegalPrincipalIds.push(principal.id);
                    }

                    // Move on to the next principal.
                    checkPrincipal(principals);
                });

            // If the target-principal is a group we need to check if the current user can view that group and tenant interactions are allowed.
            // In case the group is not public we'd need to determine our role on that group, re-using resolveEffectiveRole will
            // make sure we can interact with the group and we have a role on it if necessary.
            } else {
                resolveEffectiveRole(ctx, principal.id, principal.tenant.alias, principal.visibility, ['viewer', 'manager'], function(err, effectiveRole, canInteractWithGroup) {
                    if (err) {
                        return callback(err);
                    }

                    if (!canInteractWithGroup) {
                        canInteract = false;
                        illegalPrincipalIds.push(principal.id);
                    }

                    // Move on to the next principal.
                    checkPrincipal(principals);
                });
            }
        };

        var principals = _.values(principalObjects);
        checkPrincipal(principals);
    });
};
Пример #10
0
 var illegalPrincipalIds =  _.filter(principals, function(principal) {
     return !TenantsUtil.canInteract(resourceTenantAlias, AuthzUtil.getResourceFromId(principal.id).tenantAlias);
 });
Пример #11
0
 var invalidPrincipals = _.filter(checkTenantInteraction, function(resource) {
     return (!TenantsUtil.canInteract(ctx.user().tenant.alias, resource.tenant.alias));
 });
Пример #12
0
var resolveTargetLibraryAccess = module.exports.resolveTargetLibraryAccess = function(ctx, libraryOwner, callback) {
    var libraryTenantAlias = AuthzUtil.getResourceFromId(libraryOwner.id).tenantAlias;

    // Admin users always get private libraries
    if (ctx.user() && (ctx.user().isGlobalAdmin() || ctx.user().isTenantAdmin(libraryTenantAlias))) {
        return callback(null, true, LibraryConstants.visibility.PRIVATE);
    }

    // User is not an admin of the target library tenant, so we'll have to do some acrobatics to resolve the visibility
    // Check if we are looking at a user library
    if (PrincipalsUtil.isUser(libraryOwner.id)) {
        // If the current user is requesting his own library we can return the private stream.
        if (ctx.user() && ctx.user().id === libraryOwner.id) {
            return callback(null, true, LibraryConstants.visibility.PRIVATE);

        // A non-library owner is requesting the library, we first need to check the owner's visibility setting.    
        } else if (libraryOwner.visibility === LibraryConstants.visibility.PRIVATE || (libraryOwner.visibility === LibraryConstants.visibility.LOGGEDIN && !TenantsUtil.isLoggedIn(ctx, libraryTenantAlias))) {
            return callback(null, false);

        // We give the user the public stream in case the user is not logged in to the user's tenant
        } else if (!TenantsUtil.isLoggedIn(ctx, libraryTenantAlias)) {
            return callback(null, true, LibraryConstants.visibility.PUBLIC);

        // We give the user the logged in stream in case the current user is not the same as the library we're looking at
        } else if (ctx.user().id !== libraryOwner.id) {
            return callback(null, true, LibraryConstants.visibility.LOGGEDIN);
        }

    // Check if we are looking at a group library
    } else if (PrincipalsUtil.isGroup(libraryOwner.id)) {
        // Anonymous user can only access the public stream if the group has been set to public
        if (!ctx.user() || !TenantsUtil.canInteract(ctx.user().tenant.alias, libraryTenantAlias)) {
            if (libraryOwner.visibility === LibraryConstants.visibility.PUBLIC) {
                return callback(null, true, LibraryConstants.visibility.PUBLIC);
            } else {
                return callback(null, false);
            }
        }

        // We've established that the user is logged in.
        // We need to determine the role the user has in the group so we can show the correct stream.
        AuthzAPI.hasAnyRole(ctx.user().id, libraryOwner.id, function(err, hasAnyRole) {
            if (err) {
                return callback(err);
            }

            if (hasAnyRole) {
                return callback(null, true, LibraryConstants.visibility.PRIVATE);
            } else if (!TenantsUtil.isLoggedIn(ctx, libraryTenantAlias)) {
                if (libraryOwner.visibility === LibraryConstants.visibility.PUBLIC) {
                    return callback(null, true, LibraryConstants.visibility.PUBLIC);
                } else {
                    return callback(null, false);
                }
            } else if (libraryOwner.visibility === LibraryConstants.visibility.PRIVATE) {
                return callback(null, false);
            } else {
                return callback(null, true, LibraryConstants.visibility.LOGGEDIN);
            }
        });
    // If the passed in principal id is neither a group or user, we return an error
    } else {
        return callback({'code': 400, 'msg': 'An unrecognized principal has been provided'});
    }
};