store externalId
This commit is contained in:
parent
60f9cc8b2c
commit
d29fd81317
7 changed files with 138 additions and 4 deletions
|
@ -10,9 +10,11 @@ import {
|
||||||
} from "@rocket.chat/apps-engine/definition/api";
|
} from "@rocket.chat/apps-engine/definition/api";
|
||||||
import { EmptyRequestError } from "../errors/EmptyRequestError";
|
import { EmptyRequestError } from "../errors/EmptyRequestError";
|
||||||
import { RcSdk } from "../rc-sdk/RcSdk";
|
import { RcSdk } from "../rc-sdk/RcSdk";
|
||||||
|
import { Store } from "../store/Store";
|
||||||
|
|
||||||
export class Context {
|
export class Context {
|
||||||
public readonly rc: RcSdk;
|
public readonly rc: RcSdk;
|
||||||
|
public readonly store: Store;
|
||||||
public readonly request: IApiRequest;
|
public readonly request: IApiRequest;
|
||||||
public readonly endpoint: IApiEndpointInfo;
|
public readonly endpoint: IApiEndpointInfo;
|
||||||
public readonly read: IRead;
|
public readonly read: IRead;
|
||||||
|
@ -28,6 +30,7 @@ export class Context {
|
||||||
persis: IPersistence,
|
persis: IPersistence,
|
||||||
) {
|
) {
|
||||||
this.rc = new RcSdk(http, read);
|
this.rc = new RcSdk(http, read);
|
||||||
|
this.store = new Store(read, persis);
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.endpoint = endpoint;
|
this.endpoint = endpoint;
|
||||||
this.read = read;
|
this.read = read;
|
||||||
|
|
|
@ -22,6 +22,10 @@ export class GroupEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
|
|
||||||
const teamArgs = await Promise.all([getTeamInfo(), getTeamMembers()]);
|
const teamArgs = await Promise.all([getTeamInfo(), getTeamMembers()]);
|
||||||
const group = SCIMGroup.fromRC(...teamArgs);
|
const group = SCIMGroup.fromRC(...teamArgs);
|
||||||
|
const meta = await ctx.store.getGroup(group.id);
|
||||||
|
if (meta) {
|
||||||
|
group.externalId = meta.externalId;
|
||||||
|
}
|
||||||
return this.success(group);
|
return this.success(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +77,7 @@ export class GroupEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
public async _delete(ctx: Context): Promise<IApiResponse> {
|
public async _delete(ctx: Context): Promise<IApiResponse> {
|
||||||
const o = await ctx.rc.team.delete({ teamId: ctx.id() });
|
const o = await ctx.rc.team.delete({ teamId: ctx.id() });
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
|
await ctx.store.deleteGroup(ctx.id());
|
||||||
return this.response({
|
return this.response({
|
||||||
status: HttpStatusCode.NO_CONTENT,
|
status: HttpStatusCode.NO_CONTENT,
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,12 @@ export class GroupsEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
const groups = teamsRaw.teams.map(async (team) => {
|
const groups = teamsRaw.teams.map(async (team) => {
|
||||||
const membersRaw = await ctx.rc.team.members(team._id);
|
const membersRaw = await ctx.rc.team.members(team._id);
|
||||||
this.handleError(membersRaw);
|
this.handleError(membersRaw);
|
||||||
return SCIMGroup.fromRC(team, membersRaw.members);
|
const group = SCIMGroup.fromRC(team, membersRaw.members);
|
||||||
|
const meta = await ctx.store.getGroup(group.id);
|
||||||
|
if (meta) {
|
||||||
|
group.externalId = meta.externalId;
|
||||||
|
}
|
||||||
|
return group;
|
||||||
});
|
});
|
||||||
const list = new SCIMListResponse();
|
const list = new SCIMListResponse();
|
||||||
list.Resources = await Promise.all(groups);
|
list.Resources = await Promise.all(groups);
|
||||||
|
@ -32,6 +37,8 @@ export class GroupsEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
const m = await ctx.rc.team.members(o.team._id);
|
const m = await ctx.rc.team.members(o.team._id);
|
||||||
const group = SCIMGroup.fromRC(o.team, m.members);
|
const group = SCIMGroup.fromRC(o.team, m.members);
|
||||||
|
group.externalId = u.externalId;
|
||||||
|
await ctx.store.saveGroup(group.id, { externalId: group.externalId });
|
||||||
return this.response({
|
return this.response({
|
||||||
status: HttpStatusCode.CREATED,
|
status: HttpStatusCode.CREATED,
|
||||||
content: group,
|
content: group,
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
||||||
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
||||||
|
import {
|
||||||
|
RocketChatAssociationModel,
|
||||||
|
RocketChatAssociationRecord,
|
||||||
|
} from "@rocket.chat/apps-engine/definition/metadata";
|
||||||
import { SCIMUser } from "../scim/User";
|
import { SCIMUser } from "../scim/User";
|
||||||
import { Context } from "./Context";
|
import { Context } from "./Context";
|
||||||
import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
import { IScimEndpoint, ScimEndpoint } from "./ScimEndpoint";
|
||||||
|
@ -11,6 +15,10 @@ export class UserEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
const o = await ctx.rc.user.info(ctx.id());
|
const o = await ctx.rc.user.info(ctx.id());
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
const user = SCIMUser.fromRC(o.user);
|
const user = SCIMUser.fromRC(o.user);
|
||||||
|
const m = await ctx.store.getUser(ctx.id());
|
||||||
|
if (m) {
|
||||||
|
user.externalId = m.externalId;
|
||||||
|
}
|
||||||
return this.success(user);
|
return this.success(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +37,10 @@ export class UserEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
|
await ctx.store.saveUser(ctx.id(), { externalId: u.externalId });
|
||||||
const user = SCIMUser.fromRC(o.user);
|
const user = SCIMUser.fromRC(o.user);
|
||||||
|
user.externalId = u.externalId;
|
||||||
return this.success(user);
|
return this.success(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +50,7 @@ export class UserEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
confirmRelinquish: true,
|
confirmRelinquish: true,
|
||||||
});
|
});
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
|
await ctx.store.deleteUser(ctx.id());
|
||||||
return this.response({
|
return this.response({
|
||||||
status: HttpStatusCode.NO_CONTENT,
|
status: HttpStatusCode.NO_CONTENT,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
import { HttpStatusCode } from "@rocket.chat/apps-engine/definition/accessors";
|
||||||
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
import { IApiResponse } from "@rocket.chat/apps-engine/definition/api";
|
||||||
|
import {
|
||||||
|
RocketChatAssociationModel,
|
||||||
|
RocketChatAssociationRecord,
|
||||||
|
} from "@rocket.chat/apps-engine/definition/metadata";
|
||||||
import crypto = require("crypto");
|
import crypto = require("crypto");
|
||||||
import { SCIMListResponse } from "../scim/ListResponse";
|
import { SCIMListResponse } from "../scim/ListResponse";
|
||||||
import { SCIMUser } from "../scim/User";
|
import { SCIMUser } from "../scim/User";
|
||||||
|
@ -13,7 +17,15 @@ export class UsersEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
const o = await ctx.rc.user.list();
|
const o = await ctx.rc.user.list();
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
const list = new SCIMListResponse();
|
const list = new SCIMListResponse();
|
||||||
list.Resources = o.users.map(SCIMUser.fromRC);
|
list.Resources = await Promise.all(
|
||||||
|
o.users.map(SCIMUser.fromRC).map(async (x) => {
|
||||||
|
const meta = await ctx.store.getUser(x.id);
|
||||||
|
if (meta) {
|
||||||
|
x.externalId = meta.externalId;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}),
|
||||||
|
);
|
||||||
list.totalResults = o.total;
|
list.totalResults = o.total;
|
||||||
return this.success(list);
|
return this.success(list);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +47,8 @@ export class UsersEndpoint extends ScimEndpoint implements IScimEndpoint {
|
||||||
});
|
});
|
||||||
this.handleError(o);
|
this.handleError(o);
|
||||||
const user = SCIMUser.fromRC(o.user);
|
const user = SCIMUser.fromRC(o.user);
|
||||||
|
user.externalId = u.externalId;
|
||||||
|
await ctx.store.saveUser(user.id, { externalId: user.externalId });
|
||||||
return this.response({
|
return this.response({
|
||||||
status: HttpStatusCode.CREATED,
|
status: HttpStatusCode.CREATED,
|
||||||
content: user,
|
content: user,
|
||||||
|
|
|
@ -90,7 +90,7 @@ export class RcSdkUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async delete(body: IUserDelete): Promise<IUserDeleteResponse> {
|
public async delete(body: IUserDelete): Promise<IUserDeleteResponse> {
|
||||||
const response = await this.sdk.post(`users.delete`);
|
const response = await this.sdk.post(`users.delete`, body);
|
||||||
return this.sdk.parseResponse(response);
|
return this.sdk.parseResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
95
src/store/Store.ts
Normal file
95
src/store/Store.ts
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
import {
|
||||||
|
IPersistence,
|
||||||
|
IRead,
|
||||||
|
} from "@rocket.chat/apps-engine/definition/accessors";
|
||||||
|
import {
|
||||||
|
RocketChatAssociationModel,
|
||||||
|
RocketChatAssociationRecord,
|
||||||
|
} from "@rocket.chat/apps-engine/definition/metadata";
|
||||||
|
|
||||||
|
interface IUserMeta {
|
||||||
|
externalId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGroupMeta {
|
||||||
|
externalId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Store {
|
||||||
|
private read: IRead;
|
||||||
|
private persis: IPersistence;
|
||||||
|
constructor(read: IRead, persis: IPersistence) {
|
||||||
|
this.read = read;
|
||||||
|
this.persis = persis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteUser(id: string) {
|
||||||
|
return this.persis.removeByAssociation(
|
||||||
|
new RocketChatAssociationRecord(
|
||||||
|
RocketChatAssociationModel.USER,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveUser(id: string, meta: IUserMeta) {
|
||||||
|
return this.persis.updateByAssociation(
|
||||||
|
new RocketChatAssociationRecord(
|
||||||
|
RocketChatAssociationModel.USER,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
meta,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getUser(id: string): Promise<IUserMeta | undefined> {
|
||||||
|
const list = await this.read
|
||||||
|
.getPersistenceReader()
|
||||||
|
.readByAssociation(
|
||||||
|
new RocketChatAssociationRecord(
|
||||||
|
RocketChatAssociationModel.USER,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (list.length > 0) {
|
||||||
|
return list[0] as IUserMeta;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteGroup(id: string) {
|
||||||
|
return this.persis.removeByAssociation(
|
||||||
|
new RocketChatAssociationRecord(
|
||||||
|
RocketChatAssociationModel.ROOM,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public saveGroup(id: string, meta: IGroupMeta) {
|
||||||
|
return this.persis.updateByAssociation(
|
||||||
|
new RocketChatAssociationRecord(
|
||||||
|
RocketChatAssociationModel.ROOM,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
meta,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getGroup(id: string): Promise<IGroupMeta | undefined> {
|
||||||
|
const list = await this.read
|
||||||
|
.getPersistenceReader()
|
||||||
|
.readByAssociation(
|
||||||
|
new RocketChatAssociationRecord(
|
||||||
|
RocketChatAssociationModel.ROOM,
|
||||||
|
id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (list.length > 0) {
|
||||||
|
return list[0] as IGroupMeta;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue