add group endpoints
This commit is contained in:
parent
835c2aa53c
commit
4f1fa62c83
14 changed files with 493 additions and 139 deletions
52
Context.ts
Normal file
52
Context.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import {
|
||||
IHttp,
|
||||
IModify,
|
||||
IPersistence,
|
||||
IRead,
|
||||
} from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import {
|
||||
IApiEndpointInfo,
|
||||
IApiRequest,
|
||||
} from "@rocket.chat/apps-engine/definition/api";
|
||||
import { EmptyRequestError } from "./errors/EmptyRequestError";
|
||||
import { RcSdk } from "./rc-sdk/RcSdk";
|
||||
|
||||
export class Context {
|
||||
public readonly rc: RcSdk;
|
||||
public readonly request: IApiRequest;
|
||||
public readonly endpoint: IApiEndpointInfo;
|
||||
public readonly read: IRead;
|
||||
public readonly modify: IModify;
|
||||
public readonly http: IHttp;
|
||||
public readonly persis: IPersistence;
|
||||
constructor(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
) {
|
||||
this.rc = new RcSdk(http, read);
|
||||
this.request = request;
|
||||
this.endpoint = endpoint;
|
||||
this.read = read;
|
||||
this.modify = modify;
|
||||
this.http = http;
|
||||
this.persis = persis;
|
||||
}
|
||||
|
||||
public id(): string {
|
||||
return this.request.params.id;
|
||||
}
|
||||
|
||||
public content(): any {
|
||||
if (
|
||||
!this.request.content ||
|
||||
Object.keys(this.request.content).length === 0
|
||||
) {
|
||||
throw new EmptyRequestError();
|
||||
}
|
||||
return this.request.content;
|
||||
}
|
||||
}
|
81
GroupEndpoint.ts
Normal file
81
GroupEndpoint.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
||||
import { Context } from "./Context";
|
||||
import { SCIMGroup } from "./scim/Group";
|
||||
import { SCIMUser } from "./scim/User";
|
||||
import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
||||
|
||||
export class GroupEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||
public path = "Groups/:id";
|
||||
|
||||
public async _get(ctx: Context): Promise<IApiResponse> {
|
||||
const getTeamInfo = async () => {
|
||||
const teamRaw = await ctx.rc.team.info(ctx.id());
|
||||
this.handleError(teamRaw);
|
||||
return teamRaw.teamInfo;
|
||||
};
|
||||
|
||||
const getTeamMembers = async () => {
|
||||
const membersRaw = await ctx.rc.team.members(ctx.id());
|
||||
this.handleError(membersRaw);
|
||||
return membersRaw.members;
|
||||
};
|
||||
|
||||
const teamArgs = await Promise.all([getTeamInfo(), getTeamMembers()]);
|
||||
const group = SCIMGroup.fromRC(...teamArgs);
|
||||
return this.success(group);
|
||||
}
|
||||
|
||||
public async _put(ctx: Context): Promise<IApiResponse> {
|
||||
const membersRaw = await ctx.rc.team.members(ctx.id());
|
||||
this.handleError(membersRaw);
|
||||
const targetIds = new Set<string>(
|
||||
SCIMGroup.fromPlain(ctx.content()).members.map((x) => x.value),
|
||||
);
|
||||
const currentIds = new Set<string>(
|
||||
membersRaw.members.map((x: ITeamMember) => x.user._id),
|
||||
);
|
||||
const removeMember = async (userId: string) => {
|
||||
const removeMembersRaw = await ctx.rc.team.removeMember({
|
||||
userId,
|
||||
teamId: ctx.id(),
|
||||
});
|
||||
this.handleError(removeMembersRaw);
|
||||
};
|
||||
const addMembers = async (userIds: Array<string>) => {
|
||||
const addMembersRaw = await ctx.rc.team.addMembers({
|
||||
teamId: ctx.id(),
|
||||
members: userIds.map((userId) => ({
|
||||
userId,
|
||||
roles: ["member"],
|
||||
})),
|
||||
});
|
||||
this.handleError(addMembersRaw);
|
||||
};
|
||||
const promises: Array<Promise<void>> = [];
|
||||
for (const currentId of currentIds) {
|
||||
if (!targetIds.has(currentId)) {
|
||||
promises.push(removeMember(currentId));
|
||||
}
|
||||
}
|
||||
const addMemberIds: Array<string> = [];
|
||||
for (const targetId of targetIds) {
|
||||
if (!currentIds.has(targetId)) {
|
||||
addMemberIds.push(targetId);
|
||||
}
|
||||
}
|
||||
if (addMemberIds.length > 0) {
|
||||
promises.push(addMembers(addMemberIds));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
return this._get(ctx);
|
||||
}
|
||||
|
||||
public async _delete(ctx: Context): Promise<IApiResponse> {
|
||||
const o = await ctx.rc.team.delete({ teamId: ctx.id() });
|
||||
this.handleError(o);
|
||||
return this.response({
|
||||
status: HttpStatusCode.NO_CONTENT,
|
||||
});
|
||||
}
|
||||
}
|
53
GroupsEndpoint.ts
Normal file
53
GroupsEndpoint.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import {
|
||||
HttpStatusCode,
|
||||
IHttp,
|
||||
IModify,
|
||||
IPersistence,
|
||||
IRead,
|
||||
} from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import {
|
||||
IApiEndpointInfo,
|
||||
IApiRequest,
|
||||
IApiResponse,
|
||||
} from "@rocket.chat/apps-engine/definition/api";
|
||||
import crypto = require("crypto");
|
||||
import { Context } from "./Context";
|
||||
import { RcHttp } from "./RcHttp";
|
||||
import { SCIMGroup } from "./scim/Group";
|
||||
import { SCIMListResponse } from "./scim/ListResponse";
|
||||
import { SCIMUser } from "./scim/User";
|
||||
import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
||||
|
||||
export class GroupsEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||
public path = "Groups";
|
||||
|
||||
public async _get(ctx: Context): Promise<IApiResponse> {
|
||||
const teamsRaw = await ctx.rc.team.listAll();
|
||||
this.handleError(teamsRaw);
|
||||
const groups = teamsRaw.teams.map(async (team: ITeam) => {
|
||||
const membersRaw = await ctx.rc.team.members(team._id);
|
||||
this.handleError(membersRaw);
|
||||
return SCIMGroup.fromRC(team, membersRaw.members);
|
||||
});
|
||||
const list = new SCIMListResponse();
|
||||
list.Resources = await Promise.all(groups);
|
||||
list.totalResults = teamsRaw.total;
|
||||
return this.success(list);
|
||||
}
|
||||
|
||||
public async _post(ctx: Context): Promise<IApiResponse> {
|
||||
const u = SCIMGroup.fromPlain(ctx.content());
|
||||
const o = await ctx.rc.team.create({
|
||||
name: u.displayName,
|
||||
type: 0,
|
||||
members: u.members.map((x) => x.value),
|
||||
});
|
||||
this.handleError(o);
|
||||
const m = await ctx.rc.team.members(o.team._id);
|
||||
const group = SCIMGroup.fromRC(o.team, m.members);
|
||||
return this.response({
|
||||
status: HttpStatusCode.CREATED,
|
||||
content: group,
|
||||
});
|
||||
}
|
||||
}
|
10
RcHttp.ts
10
RcHttp.ts
|
@ -18,35 +18,35 @@ export class RcHttp implements IHttp {
|
|||
public async get(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.get(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content)
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async post(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.post(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content)
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async put(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.put(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content)
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async del(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.del(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content)
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async patch(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.patch(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content)
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import {
|
|||
import { App } from "@rocket.chat/apps-engine/definition/App";
|
||||
import { IAppInfo } from "@rocket.chat/apps-engine/definition/metadata";
|
||||
import { SettingType } from "@rocket.chat/apps-engine/definition/settings";
|
||||
import { GroupEndpoint } from "./GroupEndpoint";
|
||||
import { GroupsEndpoint } from "./GroupsEndpoint";
|
||||
|
||||
import { UserEndpoint } from "./UserEndpoint";
|
||||
import { UsersEndpoint } from "./UsersEndpoint";
|
||||
|
@ -23,7 +25,12 @@ export class ScimApp extends App {
|
|||
configuration.api.provideApi({
|
||||
visibility: ApiVisibility.PUBLIC,
|
||||
security: ApiSecurity.UNSECURE,
|
||||
endpoints: [new UsersEndpoint(this), new UserEndpoint(this)],
|
||||
endpoints: [
|
||||
new UsersEndpoint(this),
|
||||
new UserEndpoint(this),
|
||||
new GroupsEndpoint(this),
|
||||
new GroupEndpoint(this),
|
||||
],
|
||||
});
|
||||
|
||||
configuration.settings.provideSetting({
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
IApiResponse,
|
||||
} from "@rocket.chat/apps-engine/definition/api";
|
||||
import { IApp } from "@rocket.chat/apps-engine/definition/IApp";
|
||||
import { Context } from "./Context";
|
||||
import { ConflictError } from "./errors/ConflictError";
|
||||
import { EmptyRequestError } from "./errors/EmptyRequestError";
|
||||
import { EmptyResponseError } from "./errors/EmptyResponseError";
|
||||
|
@ -29,38 +30,10 @@ type ApiEndpointMethod = (
|
|||
) => Promise<IApiResponse>;
|
||||
|
||||
export interface IScimEndpoint {
|
||||
_get?(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse>;
|
||||
_post?(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse>;
|
||||
_put?(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse>;
|
||||
_delete?(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse>;
|
||||
_get?(ctx: Context): Promise<IApiResponse>;
|
||||
_post?(ctx: Context): Promise<IApiResponse>;
|
||||
_put?(ctx: Context): Promise<IApiResponse>;
|
||||
_delete?(ctx: Context): Promise<IApiResponse>;
|
||||
}
|
||||
|
||||
export abstract class ScimEndpoint extends ApiEndpoint {
|
||||
|
@ -120,12 +93,12 @@ export abstract class ScimEndpoint extends ApiEndpoint {
|
|||
|
||||
protected handleError(o: any) {
|
||||
if (!o.success) {
|
||||
if (o.error.includes("already in use")) {
|
||||
if (o.error?.includes("already in use")) {
|
||||
throw new ConflictError(
|
||||
o.error.includes("@") ? "email" : "username",
|
||||
);
|
||||
}
|
||||
if (o.error.includes("not found")) {
|
||||
if (o.error?.includes("not found")) {
|
||||
}
|
||||
throw new Error(o.error);
|
||||
}
|
||||
|
@ -146,12 +119,7 @@ export abstract class ScimEndpoint extends ApiEndpoint {
|
|||
): Promise<IApiResponse> => {
|
||||
try {
|
||||
return await method.bind(this)(
|
||||
request,
|
||||
endpoint,
|
||||
read,
|
||||
modify,
|
||||
http,
|
||||
persis,
|
||||
new Context(request, endpoint, read, modify, http, persis),
|
||||
);
|
||||
} catch (e) {
|
||||
let err: SCIMError;
|
||||
|
|
|
@ -1,75 +1,33 @@
|
|||
import {
|
||||
HttpStatusCode,
|
||||
IHttp,
|
||||
IModify,
|
||||
IPersistence,
|
||||
IRead,
|
||||
} from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import {
|
||||
IApiEndpointInfo,
|
||||
IApiRequest,
|
||||
IApiResponse,
|
||||
} from "@rocket.chat/apps-engine/definition/api";
|
||||
import { RcHttp } from "./RcHttp";
|
||||
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
||||
import { Context } from "./Context";
|
||||
import { SCIMUser } from "./scim/User";
|
||||
import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
||||
|
||||
export class UserEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||
public path = "Users/:id";
|
||||
|
||||
public async _get(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse> {
|
||||
const response = await new RcHttp(http, read).get(
|
||||
`users.info?userId=${request.params.id}`,
|
||||
);
|
||||
const o = this.parseResponse(response);
|
||||
public async _get(ctx: Context): Promise<IApiResponse> {
|
||||
const o = await ctx.rc.user.info(ctx.id());
|
||||
this.handleError(o);
|
||||
const user = SCIMUser.fromRC(o.user);
|
||||
return this.success(user);
|
||||
}
|
||||
|
||||
public async _put(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse> {
|
||||
this.hasContent(request);
|
||||
const response = await new RcHttp(http, read).post(
|
||||
"users.update",
|
||||
this.scimToUserUpdate(
|
||||
request.params.id,
|
||||
SCIMUser.fromPlain(request.content),
|
||||
),
|
||||
public async _put(ctx: Context): Promise<IApiResponse> {
|
||||
const o = await ctx.rc.user.update(
|
||||
this.scimToUserUpdate(ctx.id(), SCIMUser.fromPlain(ctx.content())),
|
||||
);
|
||||
const o = this.parseResponse(response);
|
||||
this.handleError(o);
|
||||
const user = SCIMUser.fromRC(o.user);
|
||||
return this.success(user);
|
||||
}
|
||||
|
||||
public async _delete(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse> {
|
||||
const d: IUserDelete = {
|
||||
userId: request.params.id,
|
||||
public async _delete(ctx: Context): Promise<IApiResponse> {
|
||||
const o = await ctx.rc.user.delete({
|
||||
userId: ctx.id(),
|
||||
confirmRelinquish: true,
|
||||
};
|
||||
const response = await new RcHttp(http, read).post("users.delete", d);
|
||||
const o = this.parseResponse(response);
|
||||
});
|
||||
this.handleError(o);
|
||||
return this.response({
|
||||
status: HttpStatusCode.NO_CONTENT,
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
import {
|
||||
HttpStatusCode,
|
||||
IHttp,
|
||||
IModify,
|
||||
IPersistence,
|
||||
IRead,
|
||||
} from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import {
|
||||
IApiEndpointInfo,
|
||||
IApiRequest,
|
||||
IApiResponse,
|
||||
} from "@rocket.chat/apps-engine/definition/api";
|
||||
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
||||
import crypto = require("crypto");
|
||||
import { RcHttp } from "./RcHttp";
|
||||
import { Context } from "./Context";
|
||||
import { SCIMListResponse } from "./scim/ListResponse";
|
||||
import { SCIMUser } from "./scim/User";
|
||||
import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
||||
|
@ -19,18 +9,8 @@ import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
|||
export class UsersEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||
public path = "Users";
|
||||
|
||||
public async _get(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse> {
|
||||
const response = await new RcHttp(http, read).get(
|
||||
`users.list?query={"type":{"$eq":"user"}}&fields={"createdAt":1}`,
|
||||
);
|
||||
const o = this.parseResponse(response);
|
||||
public async _get(ctx: Context): Promise<IApiResponse> {
|
||||
const o = await ctx.rc.user.list();
|
||||
this.handleError(o);
|
||||
const list = new SCIMListResponse();
|
||||
list.Resources = o.users.map(SCIMUser.fromRC);
|
||||
|
@ -38,20 +18,10 @@ export class UsersEndpoint extends ScimEndpoint implements IScimEndpoint {
|
|||
return this.success(list);
|
||||
}
|
||||
|
||||
public async _post(
|
||||
request: IApiRequest,
|
||||
endpoint: IApiEndpointInfo,
|
||||
read: IRead,
|
||||
modify: IModify,
|
||||
http: IHttp,
|
||||
persis: IPersistence,
|
||||
): Promise<IApiResponse> {
|
||||
this.hasContent(request);
|
||||
const response = await new RcHttp(http, read).post(
|
||||
`users.create`,
|
||||
this.scimToUserCreate(SCIMUser.fromPlain(request.content)),
|
||||
public async _post(ctx: Context): Promise<IApiResponse> {
|
||||
const o = await ctx.rc.user.create(
|
||||
this.scimToUserCreate(SCIMUser.fromPlain(ctx.content())),
|
||||
);
|
||||
const o = this.parseResponse(response);
|
||||
this.handleError(o);
|
||||
const user = SCIMUser.fromRC(o.user);
|
||||
return this.response({
|
||||
|
|
96
rc-sdk/RcSdk.ts
Normal file
96
rc-sdk/RcSdk.ts
Normal file
|
@ -0,0 +1,96 @@
|
|||
import {
|
||||
IHttp,
|
||||
IHttpRequest,
|
||||
IHttpResponse,
|
||||
IRead,
|
||||
} from "@rocket.chat/apps-engine/definition/accessors";
|
||||
import { EmptyResponseError } from "../errors/EmptyResponseError";
|
||||
import { JsonParseError } from "../errors/JsonParseError";
|
||||
import { RcSdkTeam } from "./RcSdkTeam";
|
||||
import { RcSdkUser } from "./RcSdkUser";
|
||||
|
||||
export class RcSdk {
|
||||
public user: RcSdkUser;
|
||||
public team: RcSdkTeam;
|
||||
private readonly baseUrl = "http://localhost:3000/api/v1";
|
||||
private readonly http: IHttp;
|
||||
private readonly read: IRead;
|
||||
|
||||
constructor(http: IHttp, read: IRead) {
|
||||
this.http = http;
|
||||
this.read = read;
|
||||
this.user = new RcSdkUser(this);
|
||||
this.team = new RcSdkTeam(this);
|
||||
}
|
||||
|
||||
public async get(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.get(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async post(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.post(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async put(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.put(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async del(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.del(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public async patch(url: string, content?: any): Promise<IHttpResponse> {
|
||||
return this.http.patch(
|
||||
this.buildUrl(url),
|
||||
await this.buildOptions(content),
|
||||
);
|
||||
}
|
||||
|
||||
public parseResponse(response: IHttpResponse): any {
|
||||
if (!response.content) {
|
||||
throw new EmptyResponseError();
|
||||
}
|
||||
let content: any;
|
||||
try {
|
||||
content = JSON.parse(response.content);
|
||||
} catch (e) {
|
||||
throw new JsonParseError();
|
||||
}
|
||||
return content;
|
||||
}
|
||||
private buildUrl(url: string): string {
|
||||
return `${this.baseUrl}/${url}`;
|
||||
}
|
||||
|
||||
private async buildOptions(content?: any): Promise<IHttpRequest> {
|
||||
const options: IHttpRequest = {
|
||||
headers: {
|
||||
"X-User-Id": await this.read
|
||||
.getEnvironmentReader()
|
||||
.getSettings()
|
||||
.getValueById("rc-user-id"),
|
||||
"X-Auth-Token": await this.read
|
||||
.getEnvironmentReader()
|
||||
.getSettings()
|
||||
.getValueById("rc-token"),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
};
|
||||
if (content !== undefined) {
|
||||
options.content = JSON.stringify(content);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
70
rc-sdk/RcSdkTeam.ts
Normal file
70
rc-sdk/RcSdkTeam.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { RcSdk } from "./RcSdk";
|
||||
|
||||
interface ITeamRemoveMemberBody {
|
||||
teamId: string;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
interface ITeamAddMemberBody {
|
||||
teamId: string;
|
||||
members: Array<{
|
||||
userId: string;
|
||||
roles: Array<string>;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface ITeamDeleteBody {
|
||||
teamId: string;
|
||||
roomsToRemove?: Array<string>;
|
||||
}
|
||||
|
||||
interface ITeamCreateBody {
|
||||
name: string;
|
||||
type: 0 | 1;
|
||||
members?: Array<string>;
|
||||
room?: {
|
||||
readOnly: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export class RcSdkTeam {
|
||||
private sdk: RcSdk;
|
||||
constructor(sdk: RcSdk) {
|
||||
this.sdk = sdk;
|
||||
}
|
||||
|
||||
public async listAll(): Promise<any> {
|
||||
const response = await this.sdk.get(`teams.listAll`);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async members(teamId: string): Promise<any> {
|
||||
const response = await this.sdk.get(`teams.members?teamId=${teamId}`);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async info(teamId: string): Promise<any> {
|
||||
const response = await this.sdk.get(`teams.info?teamId=${teamId}`);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async delete(body: ITeamDeleteBody): Promise<any> {
|
||||
const response = await this.sdk.post(`teams.delete`, body);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async create(body: ITeamCreateBody): Promise<any> {
|
||||
const response = await this.sdk.post(`teams.create`, body);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async removeMember(body: ITeamRemoveMemberBody): Promise<any> {
|
||||
const response = await this.sdk.post(`teams.removeMember`, body);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async addMembers(body: ITeamAddMemberBody): Promise<any> {
|
||||
const response = await this.sdk.post(`teams.addMembers`, body);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
}
|
35
rc-sdk/RcSdkUser.ts
Normal file
35
rc-sdk/RcSdkUser.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { RcSdk } from "./RcSdk";
|
||||
|
||||
export class RcSdkUser {
|
||||
private sdk: RcSdk;
|
||||
constructor(sdk: RcSdk) {
|
||||
this.sdk = sdk;
|
||||
}
|
||||
|
||||
public async list(): Promise<any> {
|
||||
const response = await this.sdk.get(
|
||||
`users.list?query={"type":{"$eq":"user"}}&fields={"createdAt":1}`,
|
||||
);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async info(userId: string): Promise<any> {
|
||||
const response = await this.sdk.get(`users.info?userId=${userId}`);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async update(body: IUserUpdate): Promise<any> {
|
||||
const response = await this.sdk.post(`users.update`, body);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async delete(body: IUserDelete): Promise<any> {
|
||||
const response = await this.sdk.post(`users.delete`);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
|
||||
public async create(body: IUserCreate): Promise<any> {
|
||||
const response = await this.sdk.post(`users.create`, body);
|
||||
return this.sdk.parseResponse(response);
|
||||
}
|
||||
}
|
18
rest.ts
18
rest.ts
|
@ -41,4 +41,22 @@ interface IUser {
|
|||
username: string;
|
||||
active?: boolean;
|
||||
createdAt: string;
|
||||
_updatedAt?: string;
|
||||
}
|
||||
|
||||
interface ITeam {
|
||||
_id: string;
|
||||
name: string;
|
||||
active?: boolean;
|
||||
createdAt: string;
|
||||
_updatedAt?: string;
|
||||
}
|
||||
|
||||
interface ITeamMember {
|
||||
user: {
|
||||
_id: string;
|
||||
name: string;
|
||||
username: string;
|
||||
};
|
||||
createdAt: string;
|
||||
}
|
||||
|
|
40
scim/Group.ts
Normal file
40
scim/Group.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { ISCIMGroupMember, ISCIMResource } from "./Interfaces";
|
||||
import { SCIMMeta } from "./Meta";
|
||||
|
||||
export class SCIMGroup implements ISCIMResource {
|
||||
public static fromPlain(plain: SCIMGroup): SCIMGroup {
|
||||
const group = new SCIMGroup();
|
||||
group.id = plain.id;
|
||||
group.externalId = plain.externalId;
|
||||
group.displayName = plain.displayName;
|
||||
group.members = plain.members || [];
|
||||
return group;
|
||||
}
|
||||
|
||||
public static fromRC(rc: ITeam, members: Array<ITeamMember>): SCIMGroup {
|
||||
const group = new SCIMGroup();
|
||||
group.id = rc._id;
|
||||
group.externalId = rc._id;
|
||||
group.displayName = rc.name;
|
||||
group.meta.created = new Date(rc.createdAt);
|
||||
group.meta.lastModified = new Date(rc._updatedAt || rc.createdAt);
|
||||
group.members = members.map((member) => ({
|
||||
value: member.user._id,
|
||||
$ref: `/Users/${member.user._id}`,
|
||||
display: member.user.name,
|
||||
type: "User",
|
||||
}));
|
||||
return group;
|
||||
}
|
||||
|
||||
public readonly schemas = ["urn:ietf:params:scim:schemas:core:2.0:Group"];
|
||||
public meta: SCIMMeta;
|
||||
public id: string;
|
||||
public externalId: string;
|
||||
public displayName: string;
|
||||
public members: Array<ISCIMGroupMember> = [];
|
||||
|
||||
constructor() {
|
||||
this.meta = new SCIMMeta("Group", () => this.id);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,13 @@ export interface ISCIMListResponse {
|
|||
{
|
||||
id: "c75ad752-64ae-4823-840d-ffa80929976c";
|
||||
userName: "jsmith";
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export interface ISCIMGroupMember {
|
||||
value: string;
|
||||
$ref: string;
|
||||
display: string;
|
||||
type?: "User" | "Group";
|
||||
}
|
||||
|
|
Reference in a new issue