Ver Fonte

Merge pull request #8175 from weseek/imprv/133399-133400-provider-dependent-group-sync

Imprv/133399 133400 provider dependent group sync
Futa Arai há 2 anos atrás
pai
commit
b7db22e23e

+ 1 - 0
apps/app/public/static/locales/en_US/admin.json

@@ -1068,6 +1068,7 @@
     "sync_being_executed": "There is a running external group sync process started by you or another user. The next sync cannot be executed until this finishes.",
     "sync_being_executed": "There is a running external group sync process started by you or another user. The next sync cannot be executed until this finishes.",
     "sync_succeeded": "External group sync succeeded",
     "sync_succeeded": "External group sync succeeded",
     "sync_failed": "External group sync failed",
     "sync_failed": "External group sync failed",
+    "provider": "Provider",
     "confirmation_before_sync": "Confirmation before sync",
     "confirmation_before_sync": "Confirmation before sync",
     "execution_time_warning": "If the number of groups or users is large, it might take a while until sync finishes",
     "execution_time_warning": "If the number of groups or users is large, it might take a while until sync finishes",
     "parallel_sync_forbidden": "While sync is executing, you cannot execute a different external group sync",
     "parallel_sync_forbidden": "While sync is executing, you cannot execute a different external group sync",

+ 1 - 0
apps/app/public/static/locales/ja_JP/admin.json

@@ -1078,6 +1078,7 @@
     "sync_being_executed": "自身または他のユーザが実行した外部グループ同期が終了するまで次の実行ができません",
     "sync_being_executed": "自身または他のユーザが実行した外部グループ同期が終了するまで次の実行ができません",
     "sync_succeeded": "外部グループ同期に成功しました",
     "sync_succeeded": "外部グループ同期に成功しました",
     "sync_failed": "外部グループ同期に失敗しました",
     "sync_failed": "外部グループ同期に失敗しました",
+    "provider": "プロバイダ",
     "confirmation_before_sync": "同期実行前の確認",
     "confirmation_before_sync": "同期実行前の確認",
     "execution_time_warning": "同期するグループやユーザが多い場合、同期が完了するまでに時間を要します",
     "execution_time_warning": "同期するグループやユーザが多い場合、同期が完了するまでに時間を要します",
     "parallel_sync_forbidden": "同期実行中は、他の外部グループ同期は実行できません",
     "parallel_sync_forbidden": "同期実行中は、他の外部グループ同期は実行できません",

+ 1 - 0
apps/app/public/static/locales/zh_CN/admin.json

@@ -1077,6 +1077,7 @@
     "sync_being_executed": "There is a running external group sync process started by you or another user. The next sync cannot be executed until this finishes.",
     "sync_being_executed": "There is a running external group sync process started by you or another user. The next sync cannot be executed until this finishes.",
     "sync_succeeded": "External group sync succeeded",
     "sync_succeeded": "External group sync succeeded",
     "sync_failed": "External group sync failed",
     "sync_failed": "External group sync failed",
+    "provider": "Provider",
     "confirmation_before_sync": "Confirmation before sync",
     "confirmation_before_sync": "Confirmation before sync",
     "execution_time_warning": "If the number of groups or users is large, it might take a while until sync finishes",
     "execution_time_warning": "If the number of groups or users is large, it might take a while until sync finishes",
     "parallel_sync_forbidden": "While sync is executing, you cannot execute a different external group sync",
     "parallel_sync_forbidden": "While sync is executing, you cannot execute a different external group sync",

+ 4 - 0
apps/app/src/components/Admin/UserGroup/UserGroupTable.tsx

@@ -7,6 +7,8 @@ import dateFnsFormat from 'date-fns/format';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import Link from 'next/link';
 import Link from 'next/link';
 
 
+import { IExternalUserGroupHasId } from '~/features/external-user-group/interfaces/external-user-group';
+
 
 
 type Props = {
 type Props = {
   headerLabel?: string,
   headerLabel?: string,
@@ -143,6 +145,7 @@ export const UserGroupTable: FC<Props> = ({
       <table className="table table-bordered table-user-list">
       <table className="table table-bordered table-user-list">
         <thead>
         <thead>
           <tr>
           <tr>
+            {isExternalGroup && <th>{t('external_user_group.provider')}</th>}
             <th>{t('Name')}</th>
             <th>{t('Name')}</th>
             <th>{t('Description')}</th>
             <th>{t('Description')}</th>
             <th>{t('User')}</th>
             <th>{t('User')}</th>
@@ -157,6 +160,7 @@ export const UserGroupTable: FC<Props> = ({
 
 
             return (
             return (
               <tr key={group._id}>
               <tr key={group._id}>
+                {isExternalGroup && <td>{(group as IExternalUserGroupHasId).provider}</td>}
                 {isAclEnabled
                 {isAclEnabled
                   ? (
                   ? (
                     <td><Link href={`/admin/user-group-detail/${group._id}?isExternalGroup=${isExternalGroup}`}>{group.name}</Link></td>
                     <td><Link href={`/admin/user-group-detail/${group._id}?isExternalGroup=${isExternalGroup}`}>{group.name}</Link></td>

+ 1 - 1
apps/app/src/components/SavePageControls/GrantSelector/GrantSelector.tsx

@@ -185,7 +185,7 @@ export const GrantSelector = (props: Props): JSX.Element => {
           return (
           return (
             <button key={group.item._id} type="button" className="list-group-item list-group-item-action" onClick={() => groupListItemClickHandler(group)}>
             <button key={group.item._id} type="button" className="list-group-item list-group-item-action" onClick={() => groupListItemClickHandler(group)}>
               <h5 className="d-inline-block">{group.item.name}</h5>
               <h5 className="d-inline-block">{group.item.name}</h5>
-              {group.type === GroupType.externalUserGroup && <span className="ml-2 badge badge-pill badge-info">external</span>}
+              {group.type === GroupType.externalUserGroup && <span className="ml-2 badge badge-pill badge-info">{group.item.provider}</span>}
               {/* TODO: Replace <div className="small">(TBD) List group members</div> */}
               {/* TODO: Replace <div className="small">(TBD) List group members</div> */}
             </button>
             </button>
           );
           );

+ 3 - 1
apps/app/src/features/external-user-group/server/models/external-user-group.ts

@@ -16,7 +16,7 @@ export interface ExternalUserGroupModel extends Model<ExternalUserGroupDocument>
 }
 }
 
 
 const schema = new Schema<ExternalUserGroupDocument, ExternalUserGroupModel>({
 const schema = new Schema<ExternalUserGroupDocument, ExternalUserGroupModel>({
-  name: { type: String, required: true, unique: true },
+  name: { type: String, required: true },
   parent: { type: Schema.Types.ObjectId, ref: 'ExternalUserGroup', index: true },
   parent: { type: Schema.Types.ObjectId, ref: 'ExternalUserGroup', index: true },
   description: { type: String, default: '' },
   description: { type: String, default: '' },
   externalId: { type: String, required: true, unique: true },
   externalId: { type: String, required: true, unique: true },
@@ -25,6 +25,8 @@ const schema = new Schema<ExternalUserGroupDocument, ExternalUserGroupModel>({
   timestamps: true,
   timestamps: true,
 });
 });
 schema.plugin(mongoosePaginate);
 schema.plugin(mongoosePaginate);
+// group name should be unique for each provider
+schema.index({ name: 1, provider: 1 }, { unique: true });
 
 
 /**
 /**
  * Find group that has specified externalId and update, or create one if it doesn't exist.
  * Find group that has specified externalId and update, or create one if it doesn't exist.

+ 5 - 1
apps/app/src/features/external-user-group/server/service/external-user-group-sync.ts

@@ -120,7 +120,11 @@ abstract class ExternalUserGroupSyncService implements S2sMessageHandlable {
       });
       });
 
 
       if (!preserveDeletedLdapGroups) {
       if (!preserveDeletedLdapGroups) {
-        await ExternalUserGroup.deleteMany({ _id: { $nin: existingExternalUserGroupIds }, groupProviderType: this.groupProviderType });
+        await ExternalUserGroup.deleteMany({
+          _id: { $nin: existingExternalUserGroupIds },
+          groupProviderType: this.groupProviderType,
+          provider: this.groupProviderType,
+        });
         await ExternalUserGroupRelation.removeAllInvalidRelations();
         await ExternalUserGroupRelation.removeAllInvalidRelations();
       }
       }
       socket?.emit(SocketEventName.externalUserGroup[this.groupProviderType].GroupSyncCompleted);
       socket?.emit(SocketEventName.externalUserGroup[this.groupProviderType].GroupSyncCompleted);