Skip to content

Commit 9e82d33

Browse files
committed
【feature】mvt解密支持SM4
1 parent 796c1d1 commit 9e82d33

File tree

9 files changed

+119
-24
lines changed

9 files changed

+119
-24
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@
140140
"@mapbox/mapbox-gl-style-spec": "^14.3.0",
141141
"@mapbox/vector-tile": "1.3.1",
142142
"@supermap/iclient-common": "file:src/common",
143-
"@supermap/tile-decryptor": "^0.0.2",
143+
"@supermapgis/tile-decryptor": "^1.0.0",
144144
"@turf/center": "^6.5.0",
145145
"@turf/turf": "6.5.0",
146146
"canvg": "3.0.10",

src/common/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"license": "Apache-2.0",
1616
"dependencies": {
1717
"@antv/g6": "^4.8.14",
18-
"@supermap/tile-decryptor": "^0.0.2",
1918
"echarts": "5.5.0",
2019
"fetch-ie8": "1.5.0",
2120
"fetch-jsonp": "1.1.3",

src/common/util/EncryptRequest.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export class EncryptRequest {
147147
* @category iServer Core
148148
* @description 获取矢量瓦片解密密钥
149149
* @param {string} serviceUrl - iServer 服务地址。例如:http://127.0.0.1:8090/iserver/services/xxx、http://127.0.0.1:8090/iserver/services/xxx/rest/maps、http://127.0.0.1:8090/iserver/services/xxx/restjsr/v1/vectortile。
150-
* @return {Promise} key - 矢量瓦片密钥
150+
* @return {Promise} options - 矢量瓦片密钥和加密算法类型。例如 { serviceKey, algorithm }
151151
* @usage
152152
* ```
153153
* // 浏览器
@@ -166,7 +166,7 @@ export class EncryptRequest {
166166
export async function getServiceKey(serviceUrl) {
167167
try {
168168
const workspaceServerUrl = ((serviceUrl &&
169-
serviceUrl.match(/.+(?=(\/restjsr\/v1\/vectortile\/|\/rest\/maps\/))/)) ||
169+
serviceUrl.match(/.+(?=(\/restjsr\/v1\/vectortile\/|\/rest\/maps\/|\/rest\/data\/))/)) ||
170170
[])[0];
171171
if (!workspaceServerUrl) {
172172
return;
@@ -187,7 +187,14 @@ export async function getServiceKey(serviceUrl) {
187187
method: 'get',
188188
url: svckeyUrl
189189
});
190-
return svcReponse.json();
190+
const serviceKey = await svcReponse.json();
191+
if (!serviceKey) {
192+
return;
193+
}
194+
return {
195+
serviceKey,
196+
algorithm: matchRestData.serviceEncryptInfo.encrptSpec.algorithm
197+
};
191198
} catch (error) {
192199
console.error(error);
193200
}

src/mapboxgl/core/MapExtend.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ export var MapExtend = (function () {
1616
mapboxgl.VectorTileSource.prototype.beforeLoad = async function (id, options) {
1717
const url = options && options.tiles && options.tiles[0];
1818
if (decryptSources.values.includes(id) && url) {
19-
const decryptKey = await getServiceKey(url);
20-
this.decryptKey = decryptKey;
19+
const res = await getServiceKey(url);
20+
if (res) {
21+
this.decryptOptions = {
22+
key: res.serviceKey,
23+
algorithm: res.algorithm
24+
};
25+
}
2126
}
2227
this.beforeLoadBak(id, options);
2328
};

src/openlayers/overlay/VectorTileSuperMapRest.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import GeoJSON from 'ol/format/GeoJSON';
1717
import * as olSize from 'ol/size';
1818
import Projection from 'ol/proj/Projection';
1919
import TileGrid from 'ol/tilegrid/TileGrid';
20-
import decryptTileUtil from '@supermap/tile-decryptor';
20+
import decryptTileUtil from '@supermapgis/tile-decryptor';
2121

2222
/**
2323
* @class VectorTileSuperMapRest
@@ -34,7 +34,8 @@ import decryptTileUtil from '@supermap/tile-decryptor';
3434
* @param {(string|Object)} [options.attributions='Tile Data <span>© <a href='http://support.supermap.com.cn/product/iServer.aspx' target='_blank'>SuperMap iServer</a></span> with <span>© <a href='https://iclient.supermap.io' target='_blank'>SuperMap iClient</a></span>'] - 版权描述信息。
3535
* @param {Object} [options.format] - 瓦片的要素格式化。
3636
* @param {boolean} [options.withCredentials] - 请求是否携带 cookie。
37-
* @param {boolean} [options.decrypt] - 瓦片是否需要解密。
37+
* @param {boolean|Function} [options.decrypt] - 瓦片解密。如果是 true 表示用内置的解密方法, 如 decrypt: true;如果是function 则是自定义解密如 decrypt: function ({ key, bytes })。
38+
* @param {Function} [options.decryptCompletedFunction] - 解密完成后触发。如 decryptCompletedFunction(completeData)。
3839
* @extends {ol.source.VectorTile}
3940
* @usage
4041
*/
@@ -386,15 +387,23 @@ export class VectorTileSuperMapRest extends VectorTile {
386387
const firstSource = Object.keys(options.style.sources)[0];
387388
serviceUrl = options.style.sources[firstSource].tiles[0];
388389
}
389-
this.serviceKey = await getServiceKey(serviceUrl);
390+
const res = await getServiceKey(serviceUrl);
391+
if (res) {
392+
this.decryptOptions = {
393+
key: res.serviceKey,
394+
algorithm: res.algorithm,
395+
decrypt: typeof options.decrypt === 'boolean' ? undefined : options.decrypt,
396+
decryptCompletedFunction: options.decryptCompletedFunction
397+
};
398+
}
390399
} catch (error) {
391400
console.error(error);
392401
}
393402
}
394403

395404
_decryptMvt(mvtData) {
396-
if (this.serviceKey) {
397-
return decryptTileUtil(mvtData, this.serviceKey);
405+
if (this.decryptOptions) {
406+
return decryptTileUtil({ ...this.decryptOptions, arrayBuffer: mvtData });
398407
}
399408
return mvtData;
400409
}

src/openlayers/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
"author": "SuperMap",
1616
"license": "Apache-2.0",
1717
"dependencies": {
18+
"@supermap/iclient-common": "11.2.0",
19+
"@supermapgis/tile-decryptor": "^1.0.0",
1820
"@turf/turf": "6.5.0",
1921
"mapv": "2.0.62",
2022
"ol": "7.5.2",
21-
"@supermap/iclient-common": "11.2.0",
2223
"proj4": "2.11.0",
2324
"canvg": "3.0.10",
2425
"lodash.remove": "^4.7.0",

test/common/util/EncryptRequestSpec.js

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { FetchRequest } from '../../../src/common/util/FetchRequest';
2-
import { EncryptRequest } from '../../../src/common/util/EncryptRequest';
2+
import { EncryptRequest, getServiceKey } from '../../../src/common/util/EncryptRequest';
33

44
describe('EncryptRequest', () => {
55
const serverUrl = 'http://fake.iserver.com/iserver';
@@ -71,4 +71,63 @@ describe('EncryptRequest', () => {
7171
});
7272
});
7373
});
74+
75+
it('getServiceKey', (done) => {
76+
const serviceKey = 'l3nQtAUM4li87qMfO68exInHVFQ5gS3a6pb8ySIbib8=';
77+
const encrptSpec = {
78+
keyLength: 256,
79+
attributes: 'abcd',
80+
version: '1.1',
81+
algorithm: 'AES'
82+
};
83+
const spyEncrypt = spyOn(EncryptRequest.prototype, 'request').and.callFake((options) => {
84+
if (options.url.includes('keyID1')) {
85+
return { json: () => Promise.resolve(serviceKey)};
86+
}
87+
return { json: () => Promise.resolve(null)};
88+
});
89+
const spyGet = spyOn(FetchRequest, 'get').and.callFake((url) => {
90+
if (url.includes('map-China100')) {
91+
return Promise.resolve(
92+
new Response(
93+
JSON.stringify([
94+
{
95+
serviceEncryptInfo: {
96+
encrptSpec,
97+
updateTime: 'Fri Mar 15 08:52:15 CST 2024',
98+
encrptKeyID: 'keyID1'
99+
},
100+
name: 'map-China100/rest'
101+
}
102+
])
103+
)
104+
);
105+
}
106+
return Promise.resolve(
107+
new Response(
108+
JSON.stringify([
109+
{
110+
serviceEncryptInfo: {
111+
encrptSpec,
112+
updateTime: 'Fri Mar 15 08:52:15 CST 2024',
113+
encrptKeyID: 'keyID2'
114+
},
115+
name: 'data-china100/rest'
116+
}
117+
])
118+
)
119+
);
120+
});
121+
getServiceKey('http://localhost:8090/iserver/services/map-China100/rest/maps/China').then(res => {
122+
expect(res).not.toBeUndefined();
123+
expect(res.serviceKey).toBe(serviceKey);
124+
expect(res.algorithm).toBe(encrptSpec.algorithm);
125+
getServiceKey('http://localhost:8090/iserver/services/data-China100/rest/data/datasources/China/datasets/Airport_pt').then(res => {
126+
expect(res).toBeUndefined();
127+
spyGet.calls.reset();
128+
spyEncrypt.calls.reset();
129+
done();
130+
});
131+
});
132+
});
74133
});

test/mapboxgl/core/MapExtendSpec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ describe('MapExtend mapboxgl', () => {
236236
decryptSources.add('B');
237237
expect(decryptSources.values).toEqual(['A', 'B']);
238238
await vectorSource.beforeLoad('A', source);
239-
expect(vectorSource.decryptKey).toEqual('P8h08GonNjuCB4+CAykAGmLYwNsiv4G6H8KFrFi7Afk=');
239+
expect(vectorSource.decryptOptions.key).toBe('P8h08GonNjuCB4+CAykAGmLYwNsiv4G6H8KFrFi7Afk=');
240+
expect(vectorSource.decryptOptions.algorithm).toBe('AES');
240241
} catch (error) {
241242
expect(error).toEqual(new Error('mapbox-gl cannot support plane coordinate system.'));
242243
}

test/openlayers/overlay/VectorTileSuperMapRestSpec.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,20 @@ const mapObject = {
5959
};
6060
describe('openlayers_VectorTileSuperMapRest', () => {
6161
var testDiv, map, vectorTileOptions, vectorTileSource, originalTimeout, vectorLayer, spyGet, spyPost, spyCommit;
62+
const encrptSpec = {
63+
keyLength: 256,
64+
attributes: 'abcd',
65+
version: '1.1',
66+
algorithm: 'AES'
67+
};
6268
const mockCallback = (testUrl) => {
6369
if ((url.match(/.+(?=(\/restjsr\/v1\/vectortile\/|\/rest\/maps\/))/) || [])[0] === testUrl) {
6470
return Promise.resolve(
6571
new Response(
6672
JSON.stringify([
6773
{
6874
serviceEncryptInfo: {
69-
encrptSpec: {
70-
keyLength: 256,
71-
attributes: 'abcd',
72-
version: '1.1',
73-
algorithm: 'AES'
74-
},
75+
encrptSpec,
7576
updateTime: 'Fri Mar 15 08:52:15 CST 2024',
7677
encrptKeyID: 'keyIDNAME'
7778
},
@@ -175,7 +176,8 @@ describe('openlayers_VectorTileSuperMapRest', () => {
175176

176177
it('mvt_decrypt ', (done) => {
177178
const spy = jasmine.createSpy('test');
178-
const spyEncrypt = spyOn(EncryptRequest.prototype, 'request').and.callFake(() => ({ json: () => Promise.resolve('l3nQtAUM4li87qMfO68exInHVFQ5gS3a6pb8ySIbib8=')}));
179+
const serviceKey = 'l3nQtAUM4li87qMfO68exInHVFQ5gS3a6pb8ySIbib8=';
180+
const spyEncrypt = spyOn(EncryptRequest.prototype, 'request').and.callFake(() => ({ json: () => Promise.resolve(serviceKey)}));
179181
new MapService(url).getMapInfo((serviceResult) => {
180182
map = new Map({
181183
target: 'map',
@@ -185,10 +187,11 @@ describe('openlayers_VectorTileSuperMapRest', () => {
185187
})
186188
});
187189
vectorTileOptions = VectorTileSuperMapRest.optionsFromMapJSON(url, serviceResult.result);
188-
vectorTileOptions.decrypt = true;
189190
vectorTileOptions.format = new MVT({
190191
featureClass: Feature
191192
});
193+
vectorTileOptions.decrypt = function() { return []};
194+
vectorTileOptions.decryptCompletedFunction = function() {};
192195
vectorTileOptions.tileLoadFunction = (tile) => {
193196
tile.setLoader(() => {
194197
spy();
@@ -204,7 +207,18 @@ describe('openlayers_VectorTileSuperMapRest', () => {
204207
expect(vectorTileOptions).not.toBeNull();
205208
expect(spy.calls.count()).toBe(1);
206209
expect(spyEncrypt).toHaveBeenCalled();
207-
expect(vectorTileSource.serviceKey).not.toBeUndefined();
210+
expect(vectorTileSource.decryptOptions).not.toBeUndefined();
211+
expect(vectorTileSource.decryptOptions.key).toBe(serviceKey);
212+
expect(vectorTileSource.decryptOptions.algorithm).toEqual(encrptSpec.algorithm);
213+
expect(vectorTileSource.decryptOptions.decrypt).not.toBeUndefined();
214+
expect(vectorTileSource.decryptOptions.decryptCompletedFunction).not.toBeUndefined();
215+
let testData = new Uint8Array();
216+
let resultData = vectorTileSource._decryptMvt(testData);
217+
expect(resultData.slice(0).join(',')).toEqual(testData.slice(0).join(','));
218+
vectorTileSource.decryptOptions = null;
219+
testData = new Uint8Array([5, 10]);
220+
resultData = vectorTileSource._decryptMvt(testData);
221+
expect(resultData.slice(0).join(',')).toEqual(testData.slice(0).join(','));
208222
spy.calls.reset();
209223
spyEncrypt.calls.reset();
210224
done();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy