oaeproject/Hilary

View on GitHub
packages/oae-folders/lib/invitations.js

Summary

Maintainability
C
1 day
Test Coverage
B
85%
/*!
 * Copyright 2015 Apereo Foundation (AF) Licensed under the
 * Educational Community 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://opensource.org/licenses/ECL-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.
 */

import _ from 'underscore';

import { logger } from 'oae-logger';
import { pipe, keys, filter } from 'ramda';

import * as AuthzInvitationsDAO from 'oae-authz/lib/invitations/dao.js';
import * as AuthzUtil from 'oae-authz/lib/util.js';
import * as ResourceActions from 'oae-resource/lib/actions.js';
import * as FoldersAPI from 'oae-folders';
import * as FoldersDAO from 'oae-folders/lib/internal/dao.js';

import { Context } from 'oae-context';
import { Invitation } from 'oae-authz/lib/invitations/model.js';
import { ResourceConstants } from 'oae-resource/lib/constants.js';
import { FoldersConstants } from 'oae-folders/lib/constants.js';

const { isGroupId } = AuthzUtil;

const log = logger('oae-folders-invitations');

/*!
 * When an invitation is accepted, pass on the events to update folder members and then feed back
 * the folder resources into the event emitter
 */
ResourceActions.emitter.when(
  ResourceConstants.events.ACCEPTED_INVITATION,
  (ctx, invitationHashes, memberChangeInfosByResourceId, inviterUsersById, token, callback) => {
    // Filter the invitations and changes down to only folder invitations
    const folderGroupIds = pipe(keys, filter(isGroupId))(memberChangeInfosByResourceId);
    if (_.isEmpty(folderGroupIds)) {
      return callback();
    }

    FoldersDAO.getFoldersByGroupIds(folderGroupIds, (error, folders) => {
      if (error) {
        log().warn(
          {
            err: error,
            folderGroupIds
          },
          'An error occurred while getting folders to update folder libraries after an invitation was accepted'
        );
        return callback();
      }

      if (_.isEmpty(folders)) {
        return callback();
      }

      /**
       * Invoke the "accept invitation" handler with the resources when we have them.
       * We invoke this after the get principals call for test synchronization
       */
      callback(null, folders);

      // Fire members update tasks for each folder
      _.each(folders, (folder) => {
        const invitationHash = _.findWhere(invitationHashes, { resourceId: folder.groupId });
        const inviterUser = inviterUsersById[invitationHash.inviterUserId];

        const invitationCtx = Context.fromUser(inviterUser);
        const invitation = Invitation.fromHash(invitationHash, folder, inviterUser);
        const memberChangeInfo = memberChangeInfosByResourceId[folder.groupId];

        return FoldersAPI.emitter.emit(
          FoldersConstants.events.UPDATED_FOLDER_MEMBERS,
          invitationCtx,
          folder,
          memberChangeInfo,
          { invitation }
        );
      });
    });
  }
);

/*!
 * When a folder is deleted, we delete all invitations associated to it
 */
FoldersAPI.emitter.when(FoldersConstants.events.DELETED_FOLDER, (ctx, folder, memberIds, callback) => {
  AuthzInvitationsDAO.deleteInvitationsByResourceId(folder.id, (error) => {
    if (error) {
      log().warn(
        {
          err: error,
          folderId: folder.id
        },
        'An error occurred while removing invitations after a folder was deleted'
      );
    }

    return callback();
  });
});

/**
 * Determine if the given id is a folder id
 *
 * @param  {String}     folderId    The id to check
 * @return {Boolean}                Whether or not the string was a folder id
 * @api private
 */
// eslint-disable-next-line no-unused-vars
const _isFolderId = function (folderId) {
  return AuthzUtil.isResourceId(folderId) && folderId.indexOf('f:') === 0;
};