oaeproject/Hilary

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

Summary

Maintainability
F
1 wk
Test Coverage
A
99%
/*!
 * Copyright 2014 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 { AuthzConstants } from 'oae-authz/lib/constants.js';
import * as OAE from 'oae-util/lib/oae.js';
import * as OaeUtil from 'oae-util/lib/util.js';

import * as FoldersAPI from 'oae-folders';

/**
 * @REST postFolder
 *
 * Create a new folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder
 * @FormParam   {string}            displayName         The display name of the folder
 * @FormParam   {string}            [description]       A longer description for the folder
 * @FormParam   {string}            [visibility]        The visibility of the folder. Defaults to the configured tenant default     [loggedin,private,public]
 * @FormParam   {string[]}          [managers]          Unique identifier(s) for users and groups to add as managers of the folder. The user creating the folder will be added as a manager automatically
 * @FormParam   {string[]}          [viewers]           Unique identifier(s) for users and groups to add as viewers of the folder
 * @Return      {BasicFolder}                           The created folder
 * @HttpResponse                    201                 The folder was created
 * @HttpResponse                    400                 A display name must be provided and can be at most 1000 characters long
 * @HttpResponse                    400                 A description can be at most 10000 characters long
 * @HttpResponse                    400                 An invalid visibility was provided
 * @HttpResponse                    400                 One or more of the members you're trying to add can not be added due to tenant/visibility boundaries
 * @HttpResponse                    401                 Anonymous users cannot create folders
 */
OAE.tenantRouter.on('post', '/api/folder', (request, response) => {
  const managerIds = OaeUtil.toArray(request.body.managers);
  const viewerIds = OaeUtil.toArray(request.body.viewers);

  // Hold the user roles to initialize the folder with
  const roles = {};

  // Apply the manager roles
  _.each(managerIds, (managerId) => {
    roles[managerId] = AuthzConstants.role.MANAGER;
  });

  // Apply the viewer roles
  _.each(viewerIds, (viewerId) => {
    roles[viewerId] = AuthzConstants.role.VIEWER;
  });

  FoldersAPI.createFolder(
    request.ctx,
    request.body.displayName,
    request.body.description,
    request.body.visibility,
    roles,
    (error, folder) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(201).send(folder);
    }
  );
});

/**
 * @REST getFolderManaged
 *
 * Get the folders the current user manages
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/managed
 * @Return      {FoldersLibrary}                The folders the current user manages
 * @HttpResponse                    200         The folders the current user manages are returned
 * @HttpResponse                    401         Anonymous users don't manage any folders
 */
OAE.tenantRouter.on('get', '/api/folder/managed', (request, response) => {
  FoldersAPI.getManagedFolders(request.ctx, (error, results, nextToken) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send({ results, nextToken });
  });
});

/**
 * @REST getFolderFolderId
 *
 * Get a full folder profile
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/{folderId}
 * @PathParam   {string}            folderId            The id of the folder to get
 * @Return      {Folder}                                Full folder profile
 * @HttpResponse                    200                 The full folder profile is returned
 * @HttpResponse                    400                 An invalid folder id was provided
 * @HttpResponse                    401                 You're not allowed to access this folder
 */
OAE.tenantRouter.on('get', '/api/folder/:folderId', (request, response) => {
  FoldersAPI.getFullFolderProfile(request.ctx, request.params.folderId, (error, folder) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send(folder);
  });
});

/**
 * @REST postFolderFolderId
 *
 * Update a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}
 * @PathParam   {string}            folderId            The id of the folder to update
 * @FormParam   {string}            [description]       Updated description for the folder
 * @FormParam   {string}            [displayName]       Updated display name for the folder
 * @FormParam   {string}            [visibility]        Updated visibility for the folder           [loggedin,private,public]
 * @Return      {Folder}                                Full folder profile
 * @HttpResponse                    200                 The folder is updated and its full profile is returned
 * @HttpResponse                    400                 An invalid folder id was provided
 * @HttpResponse                    400                 An invalid display name was provided
 * @HttpResponse                    400                 An invalid description was provided
 * @HttpResponse                    400                 An invalid visibility was provided
 * @HttpResponse                    401                 You're not allowed to update this folder
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId', (request, response) => {
  FoldersAPI.updateFolder(request.ctx, request.params.folderId, request.body, (error, updatedFolder) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send(updatedFolder);
  });
});

/**
 * @REST postFolderFolderIdContentVisibility
 *
 * Update the visibility of the content items in a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}
 * @PathParam   {string}            folderId            The id of the folder to update
 * @FormParam   {string}            visibility          Updated visibility for the content items in the folder           [loggedin,private,public]
 * @Return      {FolderContentVisibilityUpdate}         The content items for which the visibility could not be updated
 * @HttpResponse                    200                 The operation has completed. A set of content items that could not be updated are provided
 * @HttpResponse                    400                 An invalid folder id was provided
 * @HttpResponse                    400                 An invalid visibility was provided
 * @HttpResponse                    401                 You're not allowed to update this folder
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId/contentvisibility', (request, response) => {
  FoldersAPI.updateFolderContentVisibility(
    request.ctx,
    request.params.folderId,
    request.body.visibility,
    (error, failedContent) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      const data = { failedContent };
      return response.status(200).send(data);
    }
  );
});

/**
 * @REST deleteFolderFolderId
 *
 * Delete a folder
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /folder/{folderId}
 * @PathParam   {string}            folderId            The id of the folder to delete
 * @FormParam   {string}            deleteContent       Whether the content items in the folder should be deleted
 * @Return      {FolderContentDelete}                   The content items that could not be deleted
 * @HttpResponse                    200                 The folder has been deleted
 * @HttpResponse                    400                 An invalid folder id has been specified
 * @HttpResponse                    401                 You're not allowed to delete this folder
 * @HttpResponse                    404                 The folder did not exist
 */
OAE.tenantRouter.on('delete', '/api/folder/:folderId', (request, response) => {
  const deleteContent = OaeUtil.castToBoolean(request.body.deleteContent);
  FoldersAPI.deleteFolder(request.ctx, request.params.folderId, deleteContent, (error, failedContent) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    const data = { failedContent };
    return response.status(200).send(data);
  });
});

/**
 * @REST postFolderFolderIdShare
 *
 * Share a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}/share
 * @PathParam   {string}            folderId            The id of the folder to share
 * @FormParam   {string[]}          members             Unique identifier(s) for users and groups to share the folder with
 * @Return      {void}
 * @HttpResponse                    200                 The folder has been shared
 * @HttpResponse                    400                 An invalid folder id has been specified
 * @HttpResponse                    400                 An invalid set of principals has been provided
 * @HttpResponse                    401                 You're not allowed to share this folder
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId/share', (request, response) => {
  const viewers = OaeUtil.toArray(request.body.viewers);
  FoldersAPI.shareFolder(request.ctx, request.params.folderId, viewers, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST postFolderFolderIdMembers
 *
 * Update the members of a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}/members
 * @PathParam   {string}                    folderId            The id of the folder to update the members for
 * @BodyParam   {FolderMembersUpdate}       body                Object that describes the membership updates to apply to the folder
 * @Return      {void}
 * @HttpResponse                            200                 The members of the folder have been updated
 * @HttpResponse                            400                 An invalid folder id has been specified
 * @HttpResponse                            400                 Invalid role updates have been provided
 * @HttpResponse                            401                 You're not allowed to update the permissions for this folder
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId/members', (request, response) => {
  // Parse the incoming false values
  const permissionUpdates = {};
  _.each(request.body, (value, key) => {
    permissionUpdates[key] = OaeUtil.castToBoolean(value);
  });

  FoldersAPI.setFolderPermissions(request.ctx, request.params.folderId, permissionUpdates, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST getFolderFolderIdMembers
 *
 * Get the members of a folder and their roles
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/{folderId}/members
 * @PathParam   {string}                folderId            The id of the folder to get the members for
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The folder paging token from which to start fetching folder members
 * @Return      {MembersResponse}                           Members of the specified folder
 * @HttpResponse                    200                     The members of this folder are returned
 * @HttpResponse                    400                     An invalid folder id has been specified
 * @HttpResponse                    401                     You're not allowed to list the members of this folder
 */
OAE.tenantRouter.on('get', '/api/folder/:folderId/members', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 10, 1, 25);
  FoldersAPI.getFolderMembers(
    request.ctx,
    request.params.folderId,
    request.query.start,
    limit,
    (error, members, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).send({ results: members, nextToken });
    }
  );
});

/**
 * @REST getFolderFolderIdInvitations
 *
 * Get all the invitations associated to a folder
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/{folderId}/invitations
 * @PathParam   {string}                folderId            The id of the folder for which to get invitations
 * @Return      {InvitationsResponse}                       The invitations associated to the folder
 * @HttpResponse                        200                 Invitations available
 * @HttpResponse                        400                 A valid folder id must be provided
 * @HttpResponse                        401                 You are not allowed to get invitations for this folder
 * @HttpResponse                        404                 Folder not available
 */
OAE.tenantRouter.on('get', '/api/folder/:folderId/invitations', (request, response) => {
  FoldersAPI.getFolderInvitations(request.ctx, request.params.folderId, (error, invitations) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send({ results: invitations });
  });
});

/**
 * @REST postFolderFolderIdInvitationsEmailResend
 *
 * Resend an invitation to a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}/invitations/{email}/resend
 * @PathParam   {string}                folderId            The id of the folder for which to get invitations
 * @PathParam   {string}                email               The email for which to resend the invitation
 * @Return      {void}
 * @HttpResponse                        200                 Invitation was resent
 * @HttpResponse                        400                 A valid folder id must be provided
 * @HttpResponse                        400                 A valid email must be provided
 * @HttpResponse                        401                 You are not allowed to resend invitations for this folder
 * @HttpResponse                        404                 Folder not available
 * @HttpResponse                        404                 No invitation for the specified email exists for the folder
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId/invitations/:email/resend', (request, response) => {
  FoldersAPI.resendFolderInvitation(request.ctx, request.params.folderId, request.params.email, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST getFolderLibraryPrincipalId
 *
 * Get the folder library items for a user or group
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/library/{principalId}
 * @PathParam   {string}                principalId         The id of the principal for which to retrieve the folders
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The folder paging token from which to start fetching folders
 * @Return      {FoldersLibrary}                            The folder library items for the specified user or group
 * @HttpResponse                        200                 The library of folders for the given principal is returned
 * @HttpResponse                        400                 An invalid principal id has been specified
 * @HttpResponse                        401                 You're not allowed to list this folder library
 */
OAE.tenantRouter.on('get', '/api/folder/library/:principalId', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 12, 1, 25);
  FoldersAPI.getFoldersLibrary(
    request.ctx,
    request.params.principalId,
    request.query.start,
    limit,
    (error, results, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).send({ results, nextToken });
    }
  );
});

/**
 * @REST deleteFolderLibraryPrincipalIdLibraryId
 *
 * Remove a folder from a folder library
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /folder/library/{principalId}/{folderId}
 * @PathParam   {string}            principalId             The id of the principal from whose folder library to remove the folder
 * @PathParam   {string}            folderId                The id of the folder to remove from the library
 * @Return      {void}
 * @HttpResponse                    200                     The folder has been removed from the principal's folder library
 * @HttpResponse                    400                     An invalid principal id has been specified
 * @HttpResponse                    400                     An invalid folder id has been specified
 * @HttpResponse                    401                     You're not allowed to delete this folder from the principal's library
 */
OAE.tenantRouter.on('delete', '/api/folder/library/:principalId/:folderId', (request, response) => {
  FoldersAPI.removeFolderFromLibrary(request.ctx, request.params.principalId, request.params.folderId, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST postFolderFolderIdLibrary
 *
 * Add content items to a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}/library
 * @PathParam   {string}                    folderId            The id of the folder to add content items to
 * @FormParam   {string[]}                  contentIds          The ids of the content items that should be added to the folder
 * @Return      {void}
 * @HttpResponse                            200                 The content items have been added to the folder
 * @HttpResponse                            400                 An invalid folder id has been specified
 * @HttpResponse                            400                 One or more invalid content ids have been specified
 * @HttpResponse                            400                 You do not have access to one or more of the specified content items
 * @HttpResponse                            401                 You're not allowed to add content items to this folder
 * @HttpResponse                            404                 The folder or one or more content items do not exist
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId/library', (request, response) => {
  const contentIds = OaeUtil.toArray(request.body.contentIds);
  FoldersAPI.addContentItemsToFolder(request.ctx, request.params.folderId, contentIds, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST deleteFolderFolderIdLibrary
 *
 * Remove content items from a folder
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /folder/{folderId}/library
 * @PathParam   {string}                    folderId            The id of the folder to remove content items from
 * @BodyParam   {string[]}                  contentIds          The ids of the content items that should be removed from the folder
 * @Return      {void}
 * @HttpResponse                            200                 The content items have been removed from the folder
 * @HttpResponse                            400                 An invalid folder id has been specified
 * @HttpResponse                            400                 One or more invalid content ids have been specified
 * @HttpResponse                            401                 You're not allowed to remove content items from this folder
 * @HttpResponse                            404                 The folder or one or more content items do not exist
 */
OAE.tenantRouter.on('delete', '/api/folder/:folderId/library', (request, response) => {
  const contentIds = OaeUtil.toArray(request.body.contentIds);
  FoldersAPI.removeContentItemsFromFolder(request.ctx, request.params.folderId, contentIds, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST getFolderFolderIdLibrary
 *
 * Get the content items in a folder
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/{folderId}/library
 * @PathParam   {string}                folderId            The id of the folder for which to retrieve the content library
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The folder paging token from which to start fetching content items
 * @Return      {ContentLibrary}                            The content items in the folder
 * @HttpResponse                        200                 The content items in the folder
 * @HttpResponse                        400                 An invalid folder id has been specified
 * @HttpResponse                        400                 You do not have access to one or more of the specified content items
 * @HttpResponse                        401                 You're not allowed to list the content items in this folder
 */
OAE.tenantRouter.on('get', '/api/folder/:folderId/library', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 12, 1, 25);
  FoldersAPI.getFolderContentLibrary(
    request.ctx,
    request.params.folderId,
    request.query.start,
    limit,
    (error, results, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).send({ results, nextToken });
    }
  );
});

/**
 * @REST getFolderFolderIdMessages
 *
 * Get the messages for a folder
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /folder/{folderId}/messages
 * @PathParam   {string}                folderId            The id of the folder for which to get the messages
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The messages paging token from which to start fetching messages
 * @Return      {MessagesResponse}                          The messages in the folder
 * @HttpResponse                        200                 Folder messages available
 * @HttpResponse                        400                 A messageBoxId must be specified
 * @HttpResponse                        400                 Must provide a valid folder id
 * @HttpResponse                        401                 You are not authorized to view this folder
 * @HttpResponse                        404                 Could not find the specified folder
 */
OAE.tenantRouter.on('get', '/api/folder/:folderId/messages', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 10, 1, 25);
  FoldersAPI.getMessages(
    request.ctx,
    request.params.folderId,
    request.query.start,
    limit,
    (error, messages, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).send({ results: messages, nextToken });
    }
  );
});

/**
 * @REST postFolderFolderIdMessages
 *
 * Create a new message in a folder
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /folder/{folderId}/messages
 * @PathParam   {string}        folderId            The id of the folder to which to post the message
 * @FormParam   {string}        body                The body of the message
 * @FormParam   {number}        [replyTo]           The timestamp of the message to which this message is a reply. Not specifying this will create a top level message
 * @Return      {Message}                           The created message
 * @HttpResponse                200                 Folder message created
 * @HttpResponse                400                 A folder message can only be 100000 characters long
 * @HttpResponse                400                 A folder message must be provided
 * @HttpResponse                400                 A messageBoxId must be specified
 * @HttpResponse                400                 If the replyToCreated optional parameter is specified, it should point to an existing reply
 * @HttpResponse                400                 Invalid folder id provided
 * @HttpResponse                400                 The body of the message must be specified
 * @HttpResponse                401                 You are not authorized to post messages to this folder
 * @HttpResponse                404                 Could not find the specified folder
 */
OAE.tenantRouter.on('post', '/api/folder/:folderId/messages', (request, response) => {
  FoldersAPI.createMessage(
    request.ctx,
    request.params.folderId,
    request.body.body,
    request.body.replyTo,
    (error, message) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).send(message);
    }
  );
});

/**
 * @REST deleteFolderFolderIdMessagesCreated
 *
 * Delete a message in a folder
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /folder/{folderId}/messages/{created}
 * @PathParam   {string}                folderId            The id of the folder from which to delete the message
 * @PathParam   {number}                created             The timestamp of the message that should be deleted
 * @Return      {Message}                                   When the message has been soft deleted (because it has replies), a stripped down message object representing the deleted message will be returned, with the `deleted` parameter set to `false`. If the message has been removed entirely, no message object will be returned
 * @HttpResponse                        200                 Folder message deleted
 * @HttpResponse                        400                 A folder id must be provided
 * @HttpResponse                        400                 A messageBoxId must be specified
 * @HttpResponse                        400                 A valid integer message created timestamp must be specified
 * @HttpResponse                        400                 The createdTimestamp should point to an existing message
 * @HttpResponse                        401                 You are not authorized to delete this message
 * @HttpResponse                        404                 Could not find the specified folder
 * @HttpResponse                        404                 Could not find the specified message
 */
OAE.tenantRouter.on('delete', '/api/folder/:folderId/messages/:created', (request, response) => {
  FoldersAPI.deleteMessage(request.ctx, request.params.folderId, request.params.created, (error, message) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send(message);
  });
});