mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-03 12:16:10 +00:00
updates security specification on datasets to obtain data for gdpr related to each dataset
This commit is contained in:
parent
8388d41fa1
commit
d9eb5c4d11
@ -1,6 +1,6 @@
|
||||
import Ember from 'ember';
|
||||
import isTrackingHeaderField from 'wherehows-web/utils/validators/tracking-headers';
|
||||
import { defaultFieldDataTypeClassification, classifiers } from 'wherehows-web/constants';
|
||||
import { defaultFieldDataTypeClassification, classifiers, datasetClassifiers } from 'wherehows-web/constants';
|
||||
|
||||
const {
|
||||
get,
|
||||
@ -14,15 +14,29 @@ const {
|
||||
String: { htmlSafe }
|
||||
} = Ember;
|
||||
|
||||
// String constant identifying the classified fields on the security spec
|
||||
/**
|
||||
* String constant identifying the classified fields on the security spec
|
||||
* @type {String}
|
||||
*/
|
||||
const sourceClassificationKey = 'securitySpecification.classification';
|
||||
|
||||
/**
|
||||
* String constant identifying the datasetClassification on the security spec
|
||||
* @type {String}
|
||||
*/
|
||||
const datasetClassificationKey = 'securitySpecification.datasetClassification';
|
||||
|
||||
/**
|
||||
* List of logical types / field level data types
|
||||
* https://iwww.corp.linkedin.com/wiki/cf/display/DWH/List+of+Metadata+for+Data+Sets
|
||||
* @type {Array}
|
||||
*/
|
||||
const logicalTypes = Object.keys(defaultFieldDataTypeClassification);
|
||||
/**
|
||||
* A list of available keys for the datasetClassification map on the security specification
|
||||
* @type {Array}
|
||||
*/
|
||||
const datasetClassifiersKeys = Object.keys(datasetClassifiers);
|
||||
|
||||
// TODO: DSS-6671 Extract to constants module
|
||||
const successUpdating = 'Your changes have been successfully saved!';
|
||||
@ -69,6 +83,24 @@ export default Component.extend({
|
||||
};
|
||||
}),
|
||||
|
||||
/**
|
||||
* Computed property that is dependent on all the keys in the datasetClassification map
|
||||
* Returns a new map of datasetClassificationKey: String-> Object.<Boolean|undefined,String>
|
||||
* @type {Ember.computed}
|
||||
*/
|
||||
datasetClassification: computed(`${datasetClassificationKey}.{${datasetClassifiersKeys.join(',')}}`, function() {
|
||||
const sourceDatasetClassification = getWithDefault(this, datasetClassificationKey, {});
|
||||
|
||||
return Object.keys(datasetClassifiers).reduce((datasetClassification, classifier) => {
|
||||
datasetClassification[classifier] = {
|
||||
value: sourceDatasetClassification[classifier],
|
||||
label: datasetClassifiers[classifier]
|
||||
};
|
||||
|
||||
return datasetClassification;
|
||||
}, {});
|
||||
}),
|
||||
|
||||
/**
|
||||
* Creates a lookup table of fieldNames to classification
|
||||
* Also, the expectation is that the association from fieldName -> classification
|
||||
@ -76,9 +108,7 @@ export default Component.extend({
|
||||
* in the lookup assignment
|
||||
*/
|
||||
fieldNameToClass: computed(
|
||||
`${sourceClassificationKey}.confidential.[]`,
|
||||
`${sourceClassificationKey}.limitedDistribution.[]`,
|
||||
`${sourceClassificationKey}.highlyConfidential.[]`,
|
||||
`${sourceClassificationKey}.{confidential,limitedDistribution,highlyConfidential}.[]`,
|
||||
function () {
|
||||
const sourceClasses = getWithDefault(this, sourceClassificationKey, []);
|
||||
// Creates a lookup table of fieldNames to classification
|
||||
@ -105,9 +135,7 @@ export default Component.extend({
|
||||
* securitySpecification.classification or null if not found
|
||||
*/
|
||||
classificationDataFields: computed(
|
||||
`${sourceClassificationKey}.confidential.[]`,
|
||||
`${sourceClassificationKey}.limitedDistribution.[]`,
|
||||
`${sourceClassificationKey}.highlyConfidential.[]`,
|
||||
`${sourceClassificationKey}.{confidential,limitedDistribution,highlyConfidential}.[]`,
|
||||
'schemaFieldNamesMappedToDataTypes',
|
||||
function () {
|
||||
// Set default or if already in policy, retrieve current values from
|
||||
@ -330,6 +358,16 @@ export default Component.extend({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the source object representing the current datasetClassification map
|
||||
* @param {String} classifier the property on the datasetClassification to update
|
||||
* @param {Boolean} value flag indicating if this dataset contains member data for the specified classifier
|
||||
*/
|
||||
didChangeDatasetClassification(classifier, value) {
|
||||
const sourceDatasetClassification = getWithDefault(this, datasetClassificationKey, {});
|
||||
return set(sourceDatasetClassification, classifier, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify controller to propagate changes
|
||||
* @return {Boolean}
|
||||
|
||||
24
wherehows-web/app/constants/dataset-classification.js
Normal file
24
wherehows-web/app/constants/dataset-classification.js
Normal file
@ -0,0 +1,24 @@
|
||||
const datasetClassifiers = {
|
||||
CONNECTIONS_FOLLOWERS_FOLLOWING: 'Connections + Followers + Following',
|
||||
PROFILE_DATA: 'Profile Data',
|
||||
MESSAGING_DATA: 'Messaging Data (Metadata + Content)',
|
||||
THIRD_PARTY_INTEGRATIONS: 'Third Party Integrations In Use',
|
||||
ACTIVITY: 'Activity (Newsfeed Posts + Shares + Likes)',
|
||||
JOB_APPLICATION_FLOW_DATA: 'Job Application Flow Data (Job Application + AWLI + Resumes + Application Answers)',
|
||||
ENTERPRISE_PRODUCT_DATA: 'Enterprise Product Data',
|
||||
ACCOUNT_STATUS: 'Account Status',
|
||||
ADDRESS_BOOK_IMPORT_DATA: 'Address Book Import Data',
|
||||
MICROSOFT_DATA: 'Data from Microsoft',
|
||||
SUBSIDIARY_DATA: 'Data from companies LinkedIn acquired (Lynda, Slideshare, Connectifier, Bizo, etcetera)',
|
||||
THIRD_PARTY_DATA: 'Data from Third-party Integrations',
|
||||
DEVICE_DATA: 'Device Data',
|
||||
SEARCH_HISTORY: 'Search History',
|
||||
COURSE_VIEWING_HISTORY: 'Course Viewing History',
|
||||
WVMP: "Who's Viewed My Profile",
|
||||
PROFILE_VIEWS_BY_ME: 'Profile Views (by me)',
|
||||
ADVERTISING_DATA: 'Advertising related (LMS) Data',
|
||||
USAGE_ERROR_CONNECTIVITY_DATA: 'Usage, Error Reporting, Connectivity Data',
|
||||
OTHER_CLICKSTREAM_BROWSING_DATA: 'Other Clickstream Data + Browsing history'
|
||||
};
|
||||
|
||||
export { datasetClassifiers };
|
||||
@ -1 +1,2 @@
|
||||
export * from 'wherehows-web/constants/metadata-acquisition';
|
||||
export * from 'wherehows-web/constants/dataset-classification';
|
||||
|
||||
@ -1,14 +1,9 @@
|
||||
$user-name-width: 170px;
|
||||
$zebra: set-color(grey, light);
|
||||
|
||||
.ownership-actions {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dataset-author-row:nth-child(odd) {
|
||||
background-color: tint($zebra, 80%);
|
||||
}
|
||||
|
||||
.dataset-author-cell {
|
||||
max-width: $user-name-width;
|
||||
width: $user-name-width;
|
||||
|
||||
@ -27,3 +27,25 @@
|
||||
background-color: tint(set-color(green, green5), 65%);
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a status notification icon for a given dataset
|
||||
.dataset-tag-container {
|
||||
width: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/// A notification that a dataset contains a tag
|
||||
.dataset-tagged {
|
||||
|
||||
&::before {
|
||||
color: set-color(green, green5);
|
||||
}
|
||||
}
|
||||
|
||||
/// A notification that a dataset does not contains a tag
|
||||
.dataset-not-tagged {
|
||||
|
||||
&::before {
|
||||
color: set-color(red, red5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
restyle-var(header-color): set-color(grey, light),
|
||||
restyle-var(horizontal-padding): 10px,
|
||||
restyle-var(font-size): 16px,
|
||||
restyle-var(zebra): tint(set-color(grey, light), 80%),
|
||||
border-collapse: collapse,
|
||||
border-spacing: 0,
|
||||
text-align: left,
|
||||
@ -30,6 +31,11 @@
|
||||
restyle-modifiers: (
|
||||
'with a border': (
|
||||
border: 1px solid restyle-var(border-color)
|
||||
),
|
||||
'with stripped rows': (
|
||||
'& tr:nth-child(odd)': (
|
||||
background-color: restyle-var(zebra)
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
@ -40,4 +46,8 @@
|
||||
&--bordered {
|
||||
@include restyle(table with a border);
|
||||
}
|
||||
|
||||
&--stripped {
|
||||
@include restyle(table with stripped rows);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
<div class="alert alert-success" role="alert">{{actionMessage}}</div>
|
||||
{{/if}}
|
||||
|
||||
<table class="nacho-table nacho-table--bordered">
|
||||
<table class="nacho-table nacho-table--bordered nacho-table--stripped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User Name</th>
|
||||
@ -111,8 +111,8 @@
|
||||
<td>{{owner.idType}}</td>
|
||||
<td>{{owner.source}}</td>
|
||||
<td class="dataset-author-cell__owner-last-mod">
|
||||
{{!-- e.g Jul 18th '16, 11:11 am --}}
|
||||
{{moment-calendar owner.modifiedTime sameElse="MMM Do 'YY, h:m a"}}
|
||||
{{!-- e.g Jul 18th 2016, 11:11 am --}}
|
||||
{{moment-calendar owner.modifiedTime sameElse="MMM Do YYYY, h:mm a"}}
|
||||
</td>
|
||||
<td>
|
||||
{{ember-selector
|
||||
|
||||
@ -26,6 +26,73 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<section class="metadata-prompt">
|
||||
<header class="metadata-prompt__header">
|
||||
<p>
|
||||
This dataset contains the following types of Member data:
|
||||
|
||||
<!--TODO: DSS-6716-->
|
||||
<!-- DRY out with wrapper component that takes the link as an attribute-->
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://iwww.corp.linkedin.com/wiki/cf/display/DWH/List+of+Metadata+for+Data+Sets">
|
||||
<sup>
|
||||
More Info
|
||||
|
||||
<span class="glyphicon glyphicon-question-sign"
|
||||
title="More information on Dataset classification with examples"></span>
|
||||
</sup>
|
||||
</a>
|
||||
</p>
|
||||
</header>
|
||||
</section>
|
||||
|
||||
<table class="nacho-table nacho-table--bordered nacho-table--stripped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Dataset Content Type</th>
|
||||
<th>Is this type of member data contained in this dataset?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each-in datasetClassification as |classification props|}}
|
||||
<tr>
|
||||
<td>
|
||||
{{props.label}}
|
||||
|
||||
<span class="dataset-tag-container">
|
||||
{{#if (eq props.value true)}}
|
||||
<i class="glyphicon glyphicon-ok dataset-tagged" title="{{props.label}} is in dataset"></i>
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq props.value false)}}
|
||||
<i class="glyphicon glyphicon-remove dataset-not-tagged" title="{{props.label}} is not in dataset"></i>
|
||||
{{/if}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{{#radio-button-composer
|
||||
value=true
|
||||
name=classification
|
||||
groupValue=(readonly props.value)
|
||||
changed=(action "didChangeDatasetClassification")}}
|
||||
Yes
|
||||
{{/radio-button-composer}}
|
||||
{{#radio-button-composer
|
||||
value=false
|
||||
name=classification
|
||||
groupValue=(readonly props.value)
|
||||
changed=(action "didChangeDatasetClassification")}}
|
||||
No
|
||||
{{/radio-button-composer}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each-in}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
{{!--Renders content of `hiddenTrackingFields` to the viewer if the dataset contains hidden tracking fields--}}
|
||||
{{#if containsHiddenTrackingFields}}
|
||||
<div class="alert alert-info" role="alert">
|
||||
|
||||
@ -31,7 +31,8 @@ const createSecuritySpecification = id => {
|
||||
datasetId: id,
|
||||
geographicAffinity: { affinity: '' },
|
||||
recordOwnerType: '',
|
||||
retentionPolicy: { retentionType: '' }
|
||||
retentionPolicy: { retentionType: '' },
|
||||
datasetClassification: {}
|
||||
};
|
||||
|
||||
return JSON.parse(JSON.stringify(securitySpecification));
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/**
|
||||
* Matches a url string with a `urn` query. urn query with letters or underscore segment of any length greater
|
||||
* than 1 followed by colon and 3 forward slashes and a segment containing letters, _ or /, or none
|
||||
* than 1 followed by colon and 3 forward slashes and a segment containing letters, {, }, _ or /, or none
|
||||
* The value following the urn key is retained
|
||||
* @type {RegExp}
|
||||
*/
|
||||
const urnRegex = /([a-z_]+):\/{3}([a-z0-9_\-\/]*)/i;
|
||||
const urnRegex = /([a-z_]+):\/{3}([a-z0-9_\-\/\{\}]*)/i;
|
||||
/**
|
||||
* Asserts that a provided string matches the urn pattern above
|
||||
* @param {String} candidateUrn the string to test on
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user