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

restorecommerce / access-control-srv / 9790069742

04 Jul 2024 07:14AM UTC coverage: 74.751%. Remained the same
9790069742

push

github

Arun-KumarH
fix: revert removed event listeners and move reload to CRMD

498 of 670 branches covered (74.33%)

Branch coverage included in aggregate %.

66 of 111 new or added lines in 4 files covered. (59.46%)

322 existing lines in 4 files now uncovered.

2649 of 3540 relevant lines covered (74.83%)

54.77 hits per line

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

73.1
/src/accessControlService.ts
1
import _ from 'lodash-es';
1✔
2
import { Server } from '@restorecommerce/chassis-srv';
1✔
3
import { Events } from '@restorecommerce/kafka-client';
1✔
4
import { CommandInterface } from '@restorecommerce/chassis-srv';
1✔
5
import { ResourceManager } from './resourceManager.js';
1✔
6
import { RedisClientType } from 'redis';
1✔
7
import { AccessController } from './core/accessController.js';
1✔
8
import { loadPoliciesFromDoc } from './core/utils.js';
1✔
9
import { Logger } from 'winston';
1✔
10
import {
1✔
11
  AccessControlServiceImplementation, ReverseQuery,
1✔
12
  Request, Response, DeepPartial, Response_Decision
1✔
13
} from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/access_control.js';
1✔
14
import {
1✔
15
  CommandInterfaceServiceImplementation
1✔
16
} from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/commandinterface.js';
1✔
17
import { PolicySetWithCombinables } from './core/interfaces.js';
1✔
18

1✔
19
export class AccessControlService implements AccessControlServiceImplementation {
1✔
20
  cfg: any;
5✔
21
  logger: Logger;
5✔
22
  resourceManager: ResourceManager;
5✔
23
  accessController: AccessController;
5✔
24
  constructor(cfg: any, logger: Logger, resourceManager: ResourceManager, accessController: AccessController) {
5✔
25
    this.cfg = cfg;
5✔
26
    this.logger = logger;
5✔
27
    this.resourceManager = resourceManager;
5✔
28
    this.accessController = accessController;
5✔
29

5✔
30
    // create a resource adapter if any is defined in the config
5✔
31
    const adapterCfg = this.cfg.get('adapter') || {};
5!
32
    if (!_.isEmpty(adapterCfg)) {
5✔
33
      this.accessController.createResourceAdapter(adapterCfg);
5✔
34
    }
5✔
35
  }
5✔
36
  async loadPolicies(): Promise<void> {
5✔
37
    this.logger.info('Loading policies');
5✔
38

5✔
39
    const policiesCfg = this.cfg.get('policies');
5✔
40
    const loadType = policiesCfg?.type;
5✔
41
    switch (loadType) {
5✔
42
      case 'local':
5!
NEW
43
        const path: string = policiesCfg?.path;
×
NEW
44
        this.accessController = await loadPoliciesFromDoc(this.accessController, path);
×
NEW
45
        this.logger.silly('Policies from local files loaded');
×
NEW
46
        break;
×
47
      case 'database':
5✔
48
        const policySetService = this.resourceManager.getResourceService('policy_set');
5✔
49
        const policySets: Map<string, PolicySetWithCombinables> = await policySetService.load() || new Map();
5✔
50
        this.accessController.policySets = policySets;
5✔
51
        this.logger.silly('Policies from database loaded');
5✔
52
        break;
5✔
53
    }
5✔
54
  }
5✔
55

5✔
56
  clearPolicies(): void {
5✔
UNCOV
57
    this.accessController.clearPolicies();
×
58
  }
×
59
  /**
5✔
60
   * gRPC interface
5✔
61
   */
5✔
62
  async isAllowed(request: Request, context: any): Promise<DeepPartial<Response>> {
5✔
63
    const acsRequest: Request = {
69✔
64
      target: request.target,
69✔
65
      context: request.context ? this.unmarshallContext(request.context) : {}
69✔
66
    };
69✔
67

69✔
68
    try {
69✔
69
      return this.accessController.isAllowed(acsRequest);
69✔
70
    } catch (err: any) { // deny if any error occurs
69!
UNCOV
71
      this.logger.error('Error evaluating isAllowed request', { code: err.code, message: err.message, stack: err.stack });
×
72
      return {
×
73
        decision: Response_Decision.DENY,
×
UNCOV
74
        obligations: [],
×
UNCOV
75
        operation_status: {
×
UNCOV
76
          code: err.code,
×
UNCOV
77
          message: err.message
×
UNCOV
78
        }
×
UNCOV
79
      };
×
UNCOV
80
    }
×
81
  }
69✔
82

5✔
83
  async whatIsAllowed(request: Request, context: any): Promise<DeepPartial<ReverseQuery>> {
5✔
84
    const acsRequest: Request = {
24✔
85
      target: request.target,
24✔
86
      context: request.context ? this.unmarshallContext(request.context) : {}
24!
87
    };
24✔
88
    let whatisAllowedResponse: ReverseQuery;
24✔
89
    try {
24✔
90
      whatisAllowedResponse = await this.accessController.whatIsAllowed(acsRequest);
24✔
91
    } catch (err: any) {
24!
92
      this.logger.error('Error evaluating whatIsAllowed request', { code: err.code, message: err.message, stack: err.stack });
×
93
      return {
×
94
        operation_status: {
×
95
          code: err.code,
×
UNCOV
96
          message: err.message
×
UNCOV
97
        }
×
UNCOV
98
      };
×
UNCOV
99
    }
×
100
    return whatisAllowedResponse;
24✔
101
  }
24✔
102

5✔
103
  unmarshallContext(context: any): any {
5✔
104
    for (let prop in context) {
92✔
105
      if (_.isArray(context[prop])) {
204✔
106
        context[prop] = _.map(context.resources, this.unmarshallProtobufAny.bind(this));
92✔
107
      } else {
204✔
108
        context[prop] = this.unmarshallProtobufAny(context[prop]);
112✔
109
      }
112✔
110
    }
204✔
111
    return context;
92✔
112
  }
92✔
113

5✔
114
  unmarshallProtobufAny(object: any): any {
5✔
115
    if (!object || _.isEmpty(object.value)) {
233!
UNCOV
116
      return null;
×
UNCOV
117
    }
×
118

233✔
119
    try {
233✔
120
      return JSON.parse(object.value.toString());
233✔
121
    } catch (err: any) {
233!
UNCOV
122
      this.logger.error('Error unmarshalling object', { code: err.code, message: err.message, stack: err.stack });
×
UNCOV
123
      throw err;
×
UNCOV
124
    }
×
125
  }
233✔
126

5✔
127
}
5✔
128

1✔
129
export class AccessControlCommandInterface extends CommandInterface implements CommandInterfaceServiceImplementation {
1✔
130
  accessControlService: AccessControlService;
5✔
131
  constructor(server: Server, cfg: any, logger: Logger, events: Events,
5✔
132
    accessControlService: AccessControlService, redisClient: RedisClientType<any, any>) {
5✔
133
    super(server, cfg, logger, events, redisClient);
5✔
134
    this.accessControlService = accessControlService;
5✔
135
  }
5✔
136

5✔
137
  async restore(payload: any): Promise<any> {
5✔
138
    const result = await super.restore(payload);
×
139

×
UNCOV
140
    this.accessControlService.clearPolicies();
×
UNCOV
141
    await this.accessControlService.loadPolicies();
×
UNCOV
142
    return result;
×
UNCOV
143
  }
×
144

5✔
145
  async reset(): Promise<any> {
5✔
UNCOV
146
    const result = await super.reset();
×
UNCOV
147
    this.accessControlService.clearPolicies();
×
UNCOV
148
    return result;
×
UNCOV
149
  }
×
150
}
5✔
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

© 2025 Coveralls, Inc