export default async function handler(req: Request, reply: IReply) {
  const { teamId: teamid } = req.params
  const requestDoc: TeamMembersRelationship.TopLevelDocument = req.payload

  const team = await TeamModel
    .findOne({ teamid }, 'teamid name members')
    .populate('members', 'userid')
    .exec()

  if (team === null) {
    reply(Boom.notFound('Team not found'))
    return
  }

  const userIdsToAdd = requestDoc.data.map((user) => user.id)
  const existingUserIds = userIdsToAdd.filter((userIdToAdd) => team.members.some((actualMember) => actualMember.userid === userIdToAdd))

  if (existingUserIds.length > 0) {
    reply(Boom.badRequest('One or more users are already members of this team'))
    return
  }

  const users = await UserModel
    .find({ userid: { $in: userIdsToAdd } }, 'userid name')
    .exec()

  if (users.length !== userIdsToAdd.length) {
    reply(Boom.badRequest('One or more of the specified users could not be found'))
    return
  }

  const userObjectIds = users.map((user) => user._id)

  const teams = await TeamModel
    .find({ members: { $in: userObjectIds } }, 'teamid')
    .exec()

  if (teams.length > 0) {
    reply(Boom.badRequest('One or more of the specified users are already in a team'))
    return
  }

  team.members = team.members.concat(users.map((user) => user._id))

  await team.save()

  const eventBroadcaster: EventBroadcaster = req.server.app.eventBroadcaster
  users.forEach((user) => {
    eventBroadcaster.trigger('teams_update_members_add', {
      teamid: team.teamid,
      name: team.name,
      member: {
        userid: user.userid,
        name: user.name,
      },
    }, req.logger)
  })

  reply()
}
export async function getSortedObjectsForExport({
  types,
  objects,
  savedObjectsClient,
  exportSizeLimit,
}: ExportObjectsOptions) {
  let objectsToExport: SavedObject[] = [];
  if (objects) {
    if (objects.length > exportSizeLimit) {
      throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`);
    }
    ({ saved_objects: objectsToExport } = await savedObjectsClient.bulkGet(objects));
    const erroredObjects = objectsToExport.filter(obj => !!obj.error);
    if (erroredObjects.length) {
      const err = Boom.badRequest();
      err.output.payload.attributes = {
        objects: erroredObjects,
      };
      throw err;
    }
  } else {
    const findResponse = await savedObjectsClient.find({
      type: types,
      sortField: '_id',
      sortOrder: 'asc',
      perPage: exportSizeLimit,
    });
    if (findResponse.total > exportSizeLimit) {
      throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`);
    }
    ({ saved_objects: objectsToExport } = findResponse);
  }
  return sortObjects(objectsToExport);
}
export default async function handler(req: Request, reply: IReply) {
  const { teamId: teamid } = req.params
  const requestDoc: TeamEntriesRelationship.TopLevelDocument = req.payload

  const team = await TeamModel
    .findOne({ teamid }, 'teamid name entries')
    .populate('entries', 'hackid')
    .exec()

  if (team === null) {
    reply(Boom.notFound('Team not found'))
    return
  }

  const hackIdsToAdd = requestDoc.data.map((hack) => hack.id)
  const existingHackIds = hackIdsToAdd.filter((hackIdToAdd) => team.entries.some((actualhack) => actualhack.hackid === hackIdToAdd))

  if (existingHackIds.length > 0) {
    reply(Boom.badRequest('One or more hacks are already entries of this team'))
    return
  }

  const hacks = await HackModel
    .find({ hackid: { $in: hackIdsToAdd } }, 'hackid name')
    .exec()

  if (hacks.length !== hackIdsToAdd.length) {
    reply(Boom.badRequest('One or more of the specified hacks could not be found'))
    return
  }

  const hackObjectIds = hacks.map((hack) => hack._id)

  const teams = await TeamModel
    .find({ entries: { $in: hackObjectIds } }, 'teamid')
    .exec()

  if (teams.length > 0) {
    reply(Boom.badRequest('One or more of the specified hacks are already in a team'))
    return
  }

  team.entries = team.entries.concat(hacks.map((hack) => hack._id))

  await team.save()

  const eventBroadcaster: EventBroadcaster = req.server.app.eventBroadcaster
  hacks.forEach((hack) => {
    eventBroadcaster.trigger('teams_update_entries_add', {
      teamid: team.teamid,
      name: team.name,
      entry: {
        hackid: hack.hackid,
        name: hack.name,
      },
    }, req.logger)
  })

  reply()
}
    authenticate: (request: Request, reply: IReply) => {
      const req = request.raw.req
      const authorization = req.headers.authorization
      if (!authorization) {
        return reply(Boom.unauthorized('Credentials required', 'Basic', { realm }))
      }

      const parts = authorization.split(/\s+/)

      if (parts[0].toLowerCase() !== 'basic') {
        return reply(Boom.unauthorized('Credentials required', 'Basic', { realm }))
      }

      if (parts.length !== 2) {
        return reply(Boom.badRequest('Bad HTTP authentication header format'))
      }

      const credentialsPart = Buffer.from(parts[1], 'base64').toString()
      const sep = credentialsPart.indexOf(':')
      if (sep === -1) {
        return reply(Boom.badRequest('Bad header internal syntax'))
      }

      const username = credentialsPart.slice(0, sep)

      if (!username && !allowEmptyUsername) {
        return reply(Boom.unauthorized('HTTP authentication header missing username', 'Basic', { realm }))
      }

      const password = credentialsPart.slice(sep + 1)

      validateFunc(request, username, password, (err, isValid, credentials) => {
        credentials = credentials || null

        if (err) {
          return reply(err, null, { credentials: credentials })
        }

        if (!isValid) {
          return reply(Boom.unauthorized('Bad username or password', 'Basic', { realm }))
        }

        if (!credentials || typeof credentials !== 'object') {
          return reply(Boom.badImplementation('Bad credentials object received for Basic auth validation'))
        }

        return reply.continue({ credentials: credentials })
      })
    },
Beispiel #5
0
  public async create(space: Space) {
    if (this.useRbac()) {
      await this.ensureAuthorizedGlobally(
        this.authorization.actions.manageSpaces,
        'create',
        'Unauthorized to create spaces'
      );
    }
    const repository = this.useRbac()
      ? this.internalSavedObjectRepository
      : this.callWithRequestSavedObjectRepository;

    const { total } = await repository.find({
      type: 'space',
      page: 1,
      perPage: 0,
    });
    if (total >= this.config.get('xpack.spaces.maxSpaces')) {
      throw Boom.badRequest(
        'Unable to create Space, this exceeds the maximum number of spaces set by the xpack.spaces.maxSpaces setting'
      );
    }

    const attributes = omit(space, ['id', '_reserved']);
    const id = space.id;
    const createdSavedObject = await repository.create('space', attributes, { id });
    return this.transformSavedObjectToSpace(createdSavedObject);
  }
Beispiel #6
0
  protected _replyCallback(err: Error): void {
    if (err) {
      this._reply(boom.badRequest(err.message, err));
      return;
    }

    let model = this._resource.model;
    let data = this._resource.importItem(this._request.payload[this._rootName]);

    let query = this._createElementQuery();
    model.findOneAndUpdate(
      query,
      data,
      {new: true},
      (err: any, res: any) => {
        if (err) {
          return this._reply(boom.badRequest(err.message, err));
        }

        if (res) {
          this._replyRecord(res);
        } else if (query.__v) {
          let expandedQuery: {_id: string, __v: number} = { _id: query._id, __v: query.__v };
          this._validator.checkVersion(model, expandedQuery, (err: any) => {
            this._reply(err);
          });
        } else {
          this._reply(boom.notFound('Not Found.'));
        }
      }
    );
  }
Beispiel #7
0
 _.each(projectedResources, (projectedResource: Resource, i: number): void => {
   if (projectedResource) {
     this.__addProjection(projectedFields[i], projectedResource);
   } else {
     err = boom.badRequest('Bad projection:`' + projectedFields[i] + '`');
   }
 });
Beispiel #8
0
    it('clears session if provider requested it via setting state to `null`.', async () => {
      // Use `token` provider for this test as it's the only one that does what we want.
      config.get.withArgs('xpack.security.authProviders').returns(['token']);
      await initAuthenticator(server as any);
      authenticate = server.expose.withArgs('authenticate').lastCall.args[1];

      const request = requestFixture({ headers: { xCustomHeader: 'xxx' } });

      session.get.withArgs(request).resolves({
        state: { accessToken: 'access-xxx', refreshToken: 'refresh-xxx' },
        provider: 'token',
      });

      session.clear.resolves();

      cluster.callWithRequest.withArgs(request).rejects({ statusCode: 401 });

      cluster.callWithInternalUser
        .withArgs('shield.getAccessToken')
        .rejects(Boom.badRequest('refresh token expired'));

      const authenticationResult = await authenticate(request);
      expect(authenticationResult.redirected()).toBe(true);

      sinon.assert.calledOnce(session.clear);
      sinon.assert.calledWithExactly(session.clear, request);
    });
Beispiel #9
0
  server.ext('onPreResponse', (request, reply) => {

    const res = request.response;
    if (res.isBoom) {

      const output = res['output']

      if (output.statusCode === 400) {

        if (!output.payload.errorCode){
          const e = Boom.badRequest(res['output'].payload.message)
          e.output.payload['errorCode'] = 'ERR_VALIDATION'
          return reply(e)
        }
      }

      if (output.statusCode === 401 && output.headers['WWW-Authenticate'] === 'Token') {
        request.log(['error', 'authentication'], output.payload.message || output.payload.error, output)
        if (!output.payload.errorCode){
          const e = Boom.unauthorized(output.payload.message)
          e.output.payload['errorCode'] = 'ERR_INVALID_JWT'
          return reply(e)
        }
      }

      request.log(['error'], output.payload.message || output.payload.error, output)
      return reply.continue()

    }
    return reply.continue();
  })
export async function injectNestedDependencies(
  savedObjects: SavedObject[],
  savedObjectsClient: SavedObjectsClient
) {
  const savedObjectsMap = new Map<string, SavedObject>();
  for (const savedObject of savedObjects) {
    savedObjectsMap.set(`${savedObject.type}:${savedObject.id}`, savedObject);
  }
  let objectsToFetch = getObjectReferencesToFetch(savedObjectsMap);
  while (objectsToFetch.length > 0) {
    const bulkGetResponse = await savedObjectsClient.bulkGet(objectsToFetch);
    // Check for errors
    const erroredObjects = bulkGetResponse.saved_objects.filter(obj => !!obj.error);
    if (erroredObjects.length) {
      const err = Boom.badRequest();
      err.output.payload.attributes = {
        objects: erroredObjects,
      };
      throw err;
    }
    // Push to array result
    for (const savedObject of bulkGetResponse.saved_objects) {
      savedObjectsMap.set(`${savedObject.type}:${savedObject.id}`, savedObject);
    }
    objectsToFetch = getObjectReferencesToFetch(savedObjectsMap);
  }
  return [...savedObjectsMap.values()];
}