Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(portal): new addGroupUsers() function #585

Merged
merged 4 commits into from
Jun 17, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### [Unreleased][HEAD]

* New Features
* A new [`addGroupUsers`](https://esri.github.io/arcgis-rest-js/api/portal/addGroupUsers/) method has been added to add members to a given group.

## [2.0.4] - June 14th 2019

### @esri/arcgis-rest-auth
Expand Down
141 changes: 141 additions & 0 deletions packages/arcgis-rest-portal/src/groups/add-users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* Copyright (c) 2017-2018 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

import {
request,
IRequestOptions,
ArcGISRequestError
} from "@esri/arcgis-rest-request";

import { getPortalUrl } from "../util/get-portal-url";
import { chunk } from "../util/array";

export interface IAddGroupUsersOptions extends IRequestOptions {
/**
* Group ID
*/
id: string;
/**
* An array of usernames to be added to the group as group members
*/
users?: string[];
/**
* An array of usernames to be added to the group as group admins
*/
admins?: string[];
}

export interface IAddGroupUsersResult {
/**
* An array of usernames that were not added
*/
notAdded?: string[];
/**
* An array of request errors
*/
errors?: ArcGISRequestError[];
}

/**
* ```js
* import { addGroupUsers } from "@esri/arcgis-rest-portal";
* //
* addGroupUsers({
* id: groupId,
* users: ["username1", "username2"],
* admins: ["username3"],
* authentication
* })
* .then(response);
* ```
* Add users to a group. See the [REST Documentation](https://developers.arcgis.com/rest/users-groups-and-items/add-users-to-group.htm) for more information.
*
* @param requestOptions - Options for the request
* @returns A Promise
*/
export function addGroupUsers(
requestOptions: IAddGroupUsersOptions
): Promise<IAddGroupUsersResult> {
const id = requestOptions.id;
const url = `${getPortalUrl(requestOptions)}/community/groups/${id}/addUsers`;
const baseOptions = Object.assign({}, requestOptions, {
admins: undefined,
users: undefined
});

const batchRequestOptions = [
..._prepareRequests("users", requestOptions.users, baseOptions),
..._prepareRequests("admins", requestOptions.admins, baseOptions)
];

const promises = batchRequestOptions.map(options =>
_sendSafeRequest(url, options)
);

return Promise.all(promises).then(_consolidateRequestResults);
}

function _prepareRequests(
type: "admins" | "users",
usernames: string[],
baseOptions: IAddGroupUsersOptions
): IAddGroupUsersOptions[] {
if (!usernames || usernames.length < 1) {
return [];
}

// the ArcGIS REST API only allows to add no more than 25 users per request,
// see https://developers.arcgis.com/rest/users-groups-and-items/add-users-to-group.htm
const userChunks: string[][] = chunk<string>(usernames, 25);

return userChunks.map(users =>
_generateRequestOptions(type, users, baseOptions)
);
}

function _generateRequestOptions(
type: "admins" | "users",
usernames: string[],
baseOptions: IAddGroupUsersOptions
) {
return Object.assign({}, baseOptions, {
[type]: usernames,
params: {
...baseOptions.params,
[type]: usernames
}
});
}

function _sendSafeRequest(
url: string,
requestOptions: IAddGroupUsersOptions
): Promise<IAddGroupUsersResult> {
return request(url, requestOptions).catch(error => {
return {
// the request should either add users or admins, not both
notAdded: requestOptions.users || requestOptions.admins,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should populate notAdded when there are errors. We don't want them to get mixed up w/ any that were not added b/c they were already in the group.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the code

errors: [error]
};
});
}

function _consolidateRequestResults(
results: IAddGroupUsersResult[]
): IAddGroupUsersResult {
const notAdded = results
.filter(result => result.notAdded)
.reduce((collection, result) => collection.concat(result.notAdded), []);

const errors = results
.filter(result => result.errors)
.reduce((collection, result) => collection.concat(result.errors), []);

const consolidated: IAddGroupUsersResult = { notAdded };

if (errors.length > 0) {
consolidated.errors = errors;
}

return consolidated;
}
1 change: 1 addition & 0 deletions packages/arcgis-rest-portal/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from "./items/search";
export * from "./items/update";
export * from "./items/helpers";

export * from "./groups/add-users";
export * from "./groups/create";
export * from "./groups/get";
export * from "./groups/helpers";
Expand Down
16 changes: 16 additions & 0 deletions packages/arcgis-rest-portal/src/util/array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Copyright (c) 2019 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

export function chunk<T>(array: T[], size: number) {
if (array.length === 0) {
return [];
}

const chunks = [];

for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}

return chunks;
}
Loading