• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alkem-io / server / #9106

22 Jan 2025 04:03PM UTC coverage: 14.35%. First build
#9106

Pull #4814

travis-ci

Pull Request #4814: RoleSet on organizations + platform

84 of 4951 branches covered (1.7%)

Branch coverage included in aggregate %.

48 of 312 new or added lines in 27 files covered. (15.38%)

2292 of 11606 relevant lines covered (19.75%)

7.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

12.79
/src/platform/platform/platform.service.ts
1
import { LogContext } from '@common/enums/logging.context';
54✔
2
import { EntityNotFoundException } from '@common/exceptions/entity.not.found.exception';
54✔
3
import { ILibrary } from '@library/library/library.interface';
4
import { Inject, Injectable, LoggerService } from '@nestjs/common';
54✔
5
import { InjectRepository } from '@nestjs/typeorm';
54✔
6
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
54✔
7
import {
54✔
8
  EntityManager,
9
  FindOneOptions,
10
  FindOptionsRelations,
11
  Repository,
12
} from 'typeorm';
13
import { Platform } from './platform.entity';
54✔
14
import { IPlatform } from './platform.interface';
15
import { IStorageAggregator } from '@domain/storage/storage-aggregator/storage.aggregator.interface';
16
import { IAuthorizationPolicy } from '@domain/common/authorization-policy';
17
import { ReleaseDiscussionOutput } from './dto/release.discussion.dto';
18
import { ForumService } from '@platform/forum/forum.service';
54✔
19
import { IForum } from '@platform/forum/forum.interface';
20
import { ForumDiscussionCategory } from '@common/enums/forum.discussion.category';
54✔
21
import { MessagingService } from '@domain/communication/messaging/messaging.service';
54✔
22
import { IMessaging } from '@domain/communication/messaging/messaging.interface';
23
import { Discussion } from '@platform/forum-discussion/discussion.entity';
24
import { ITemplatesManager } from '@domain/template/templates-manager/templates.manager.interface';
25
import { ILicensingFramework } from '@platform/licensing/credential-based/licensing-framework/licensing.framework.interface';
26
import { IRoleSet } from '@domain/access/role-set';
27

28
@Injectable()
54✔
29
export class PlatformService {
30
  constructor(
×
31
    private forumService: ForumService,
×
32
    private readonly messagingService: MessagingService,
33
    private entityManager: EntityManager,
×
34
    @InjectRepository(Platform)
×
35
    private platformRepository: Repository<Platform>,
36
    @Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService
37
  ) {}
38

39
  async getPlatformOrFail(
40
    options?: FindOneOptions<Platform>
×
41
  ): Promise<IPlatform | never> {
×
42
    let platform: IPlatform | null = null;
43
    platform = (
44
      await this.platformRepository.find({ take: 1, ...options })
45
    )?.[0];
×
46

×
47
    if (!platform) {
48
      throw new EntityNotFoundException(
49
        'No Platform found!',
50
        LogContext.PLATFORM
51
      );
×
52
    }
53

54
    // Ensure notificationEmailBlacklist is initialized
55
    if (platform.settings?.integration) {
×
56
      if (!platform.settings.integration.notificationEmailBlacklist) {
57
        platform.settings.integration.notificationEmailBlacklist = [];
58
      }
59
    }
60

61
    return platform;
×
62
  }
63

64
  async savePlatform(platform: IPlatform): Promise<IPlatform> {
×
65
    return await this.platformRepository.save(platform);
×
66
  }
×
67

68
  async getLibraryOrFail(
69
    relations?: FindOptionsRelations<IPlatform>
70
  ): Promise<ILibrary> {
71
    const platform = await this.getPlatformOrFail({
×
72
      relations: { library: true, ...relations },
73
    });
74
    const library = platform.library;
75
    if (!library) {
×
76
      throw new EntityNotFoundException(
77
        'No Platform Library found!',
78
        LogContext.PLATFORM
×
79
      );
×
80
    }
×
81
    return library;
82
  }
83

84
  async getForumOrFail(): Promise<IForum> {
85
    const platform = await this.getPlatformOrFail({
×
86
      relations: { forum: true },
87
    });
88
    const forum = platform.forum;
89
    if (!forum) {
×
90
      throw new EntityNotFoundException(
91
        'No Platform Forum found!',
92
        LogContext.PLATFORM
×
93
      );
×
94
    }
95
    return forum;
96
  }
97

98
  async getTemplatesManagerOrFail(): Promise<ITemplatesManager> {
99
    const platform = await this.getPlatformOrFail({
×
100
      relations: { templatesManager: true },
101
    });
102
    if (!platform || !platform.templatesManager) {
103
      throw new EntityNotFoundException(
×
104
        'Unable to find templatesManager for platform',
105
        LogContext.PLATFORM
106
      );
×
107
    }
×
108

×
109
    return platform.templatesManager;
110
  }
111

×
112
  async ensureForumCreated(): Promise<IForum> {
×
113
    const platform = await this.getPlatformOrFail({
114
      relations: { forum: true },
×
115
    });
116
    const forum = platform.forum;
117
    if (!forum) {
118
      // Forum is a direct child of Platform. Since Platform has no Matrix Space,
119
      // Forum becomes a root-level Matrix Space (no parent).
120
      platform.forum = await this.forumService.createForum(
×
121
        Object.values(ForumDiscussionCategory)
122
      );
123
      await this.savePlatform(platform);
124
      return platform.forum;
125
    }
×
126
    return forum;
127
  }
×
128

×
129
  async ensureMessagingCreated(): Promise<IMessaging> {
130
    const platform = await this.getPlatformOrFail({
131
      relations: { messaging: true },
132
    });
133
    const messaging = platform.messaging;
134
    if (!messaging) {
×
135
      platform.messaging = await this.messagingService.createMessaging();
136
      await this.savePlatform(platform);
137
      return platform.messaging;
138
    }
×
139
    return messaging;
140
  }
141

142
  /**
143
   * @deprecated Use ensureMessagingCreated instead
144
   */
145
  async ensureConversationsSetCreated(): Promise<IMessaging> {
×
146
    return this.ensureMessagingCreated();
×
147
  }
×
148

149
  async getStorageAggregator(
150
    platformInput: IPlatform
151
  ): Promise<IStorageAggregator> {
152
    const platform = await this.getPlatformOrFail({
×
153
      relations: {
154
        storageAggregator: true,
155
      },
156
    });
157
    const storageAggregator = platform.storageAggregator;
158

×
159
    if (!storageAggregator) {
160
      throw new EntityNotFoundException(
161
        `Unable to find storage aggregator for Platform: ${platformInput.id}`,
162
        LogContext.PLATFORM
163
      );
×
164
    }
165

×
166
    return storageAggregator;
×
167
  }
168

169
  async getLicensingFramework(
170
    platformInput: IPlatform
171
  ): Promise<ILicensingFramework> {
172
    const platform = await this.getPlatformOrFail({
×
173
      relations: {
174
        licensingFramework: true,
175
      },
NEW
176
    });
×
177
    const licensing = platform.licensingFramework;
178

179
    if (!licensing) {
180
      throw new EntityNotFoundException(
NEW
181
        `Unable to find Licensing for Platform: ${platformInput.id}`,
×
182
        LogContext.PLATFORM
NEW
183
      );
×
NEW
184
    }
×
185

186
    return licensing;
187
  }
188

189
  async getRoleSetOrFail(): Promise<IRoleSet | never> {
NEW
190
    const platform = await this.getPlatformOrFail({
×
191
      relations: {
192
        roleSet: true,
193
      },
194
    });
×
195
    const roleSet = platform.roleSet;
196

×
197
    if (!roleSet) {
×
198
      throw new EntityNotFoundException(
199
        'Unable to find RoleSet for Platform',
200
        LogContext.PLATFORM
201
      );
202
    }
203

×
204
    return roleSet;
205
  }
206

207
  getAuthorizationPolicy(platform: IPlatform): IAuthorizationPolicy {
208
    const authorization = platform.authorization;
209

210
    if (!authorization) {
×
211
      throw new EntityNotFoundException(
×
212
        `Unable to find Authorization Policy for Platform: ${platform.id}`,
213
        LogContext.PLATFORM
214
      );
215
    }
216

217
    return authorization;
218
  }
×
219

220
  public async getLatestReleaseDiscussion(): Promise<
221
    ReleaseDiscussionOutput | undefined
×
222
  > {
223
    let latestDiscussion: Discussion | undefined;
224
    try {
225
      latestDiscussion = await this.entityManager
226
        .getRepository(Discussion)
227
        .findOneOrFail({
228
          where: { category: ForumDiscussionCategory.RELEASES },
229
          order: { createdDate: 'DESC' },
230
        });
231
    } catch {
232
      return undefined;
233
    }
234

235
    return { nameID: latestDiscussion.nameID, id: latestDiscussion.id };
236
  }
237
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc