Skip to content

Commit

Permalink
using introspection strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
vogievetsky committed Jan 28, 2016
1 parent 271d5a7 commit 906e453
Show file tree
Hide file tree
Showing 23 changed files with 285 additions and 108 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,17 @@ Then you are ready to

**Recent improvements:**

- All new introspection code
- Better comparison behavior and legend interaction
- Support for query time lookups (ex. `$language.lookup('wikipedia-language-lookup')`)
- Support for the extract function (ex. `resourceVersion: $resource.extract("(\d+\.\d+\.\d+)")`)
- Custom dimensions (ex. `$user.substr(0,1)`)
- Better legend for time series comparison

**We will be working on:**

- Additional visualizations (bar chart, geo, heatmap)
- Exclusion filters
- Better time selection
- String / RegExp filters
- Removing strict limits on dimension values
- Better time selection with date picker
- Various additions, improvements and fixes to make the app more complete

Expand Down
2 changes: 1 addition & 1 deletion config.yaml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# The port on which the Pivot server will listen on
port: 9090

# Run in verbose mode and print the querries sent to the server
# Run in verbose mode and print the queries sent to the server
#verbose: true

# A Druid broker node that can serve data (only used if you have Druid based data source)
Expand Down
19 changes: 19 additions & 0 deletions docs/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Security in Pivot

Pivot does not currently have a concept of a user. Everyone who has access to a given Pivot server has equal access to that server.
Pivot can act as a 'gatekeeper' for Druid or any supported datasource via the config.

### Data source level access

It is possible to restrict which data sources users have access to by explicitly defining in the config all the data sources that you want the users to see and disabling source discovery.
This will prevent any data sources not explicitly defined from being quarried through Pivot.

### Column level access

It is possible restrict which columns users have access to by explicitly defining all the dimensions and measures that you want the users to see and disabling introspection.
Any query asking for a column that was not explicitly defined in the dimensions or measures will fail.

### Row level access

A Pivot dataSource can define a `subsetFilter` that is a boolean Plywood filter clause that will be silently applied to all queries made to that data source.
For example if you wanted your users to only see the data for "United States" you could add `subsetFilter: $country == "United States"` to the data source definition.
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@
"body-parser": "1.14.2",
"chronoshift": "0.3.7",
"compression": "1.6.1",
"d3": "3.5.13",
"d3": "3.5.14",
"debug": "2.2.0",
"express": "4.13.4",
"express-handlebars": "2.0.1",
"express-handlebars": "3.0.0",
"fs-promise": "0.3.1",
"immutable": "3.7.6",
"immutable-class": "0.3.8",
"immutable-class": "0.3.9",
"js-yaml": "3.5.2",
"lz-string": "1.4.4",
"morgan": "1.6.1",
"nopt": "3.0.6",
"numeral": "1.5.3",
"plywood": "0.8.1",
"plywood-druid-requester": "1.2.5",
"plywood": "0.8.3",
"plywood-druid-requester": "1.2.6",
"plywood-mysql-requester": "1.1.5",
"q": "1.4.1",
"qajax": "1.3.0",
Expand All @@ -51,18 +51,18 @@
"react-dom": "0.14.6"
},
"devDependencies": {
"chai": "3.4.1",
"fs-extra": "0.26.4",
"chai": "3.5.0",
"fs-extra": "0.26.5",
"gulp": "3.9.0",
"gulp-watch": "4.3.5",
"jsdom": "7.2.2",
"jsdom": "8.0.0",
"laborer": "2.4.5",
"mkdirp": "0.5.1",
"mocha": "2.3.4",
"mocha": "2.4.4",
"react-addons-test-utils": "0.14.6",
"replace": "0.3.0",
"run-sequence": "1.1.5",
"sinon": "1.17.2",
"sinon": "1.17.3",
"underscore": "1.8.3"
}
}
7 changes: 3 additions & 4 deletions src/common/models/colors/colors.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { Colors } from './colors';
import { Colors, ColorsJS } from './colors';

describe('Colors', () => {
it('is an immutable class', () => {
testImmutableClass(Colors, [
testImmutableClass<ColorsJS>(Colors, [
{
dimension: 'country',
limit: 5
Expand All @@ -35,8 +35,7 @@ describe('Colors', () => {
},
{
dimension: 'country',
values: { '0': 'USA', '1': 'UK', '2': 'India' },
sameAsLimit: true
values: { '0': 'USA', '1': 'UK', '2': 'India' }
}
]);
});
Expand Down
4 changes: 2 additions & 2 deletions src/common/models/data-source/data-source.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { DataSource } from './data-source';
import { DataSource, DataSourceJS } from './data-source';

describe('DataSource', () => {

it('is an immutable class', () => {
testImmutableClass(DataSource, [
testImmutableClass<DataSourceJS>(DataSource, [
{
name: 'twitter',
title: 'Twitter',
Expand Down
24 changes: 11 additions & 13 deletions src/common/models/data-source/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,12 @@ export class DataSource implements Instance<DataSourceValue, DataSourceJS> {
case 'STRING':
if (attribute.special === 'unique') {
if (!autofillMeasures) continue;
expression = $main.countDistinct($(name));
if (this.getMeasureByExpression(expression)) continue;
measures = measures.push(new Measure({
name,
expression,
format: Measure.INTEGER_FORMAT
}));

var newMeasures = Measure.measuresFromAttributeInfo(attribute);
newMeasures.forEach((newMeasure) => {
if (this.getMeasureByExpression(newMeasure.expression)) return;
measures = measures.push(newMeasure);
});
} else {
if (!autofillDimensions) continue;
expression = $(name);
Expand All @@ -460,14 +459,13 @@ export class DataSource implements Instance<DataSourceValue, DataSourceJS> {
break;

case 'NUMBER':
if (attribute.special === 'histogram') continue;
if (!autofillMeasures) continue;

expression = Measure.getExpressionForName(name);

if (this.getMeasureByExpression(expression)) continue;
var newMeasure = new Measure({ name, expression });
measures = (name === 'count') ? measures.unshift(newMeasure) : measures.push(newMeasure);
var newMeasures = Measure.measuresFromAttributeInfo(attribute);
newMeasures.forEach((newMeasure) => {
if (this.getMeasureByExpression(newMeasure.expression)) return;
measures = (name === 'count') ? measures.unshift(newMeasure) : measures.push(newMeasure);
});
break;

default:
Expand Down
4 changes: 2 additions & 2 deletions src/common/models/dimension/dimension.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { Dimension } from './dimension';
import { Dimension, DimensionJS } from './dimension';

describe('Dimension', () => {
it('is an immutable class', () => {
testImmutableClass(Dimension, [
testImmutableClass<DimensionJS>(Dimension, [
{
name: 'country',
title: 'important countries',
Expand Down
8 changes: 4 additions & 4 deletions src/common/models/essence/essence.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { testImmutableClass } from 'immutable-class/build/tester';
import { List } from 'immutable';

import { $, Expression } from 'plywood';
import { Essence } from './essence';
import { DataSource } from "../data-source/data-source";
import { Essence, EssenceJS } from './essence';
import { DataSource, DataSourceJS } from "../data-source/data-source";

describe('Essence', () => {
var dataSourceJS = {
var dataSourceJS: DataSourceJS = {
name: 'twitter',
title: 'Twitter',
engine: 'druid',
Expand Down Expand Up @@ -71,7 +71,7 @@ describe('Essence', () => {
}
];
it('is an immutable class', () => {
testImmutableClass(Essence, [
testImmutableClass<EssenceJS>(Essence, [
{
dataSource: 'twitter',
visualization: 'viz1',
Expand Down
4 changes: 2 additions & 2 deletions src/common/models/filter-clause/filter-clause.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { FilterClause } from './filter-clause';
import { FilterClause, FilterClauseJS } from './filter-clause';

describe('FilterClause', () => {
it('is an immutable class', () => {
testImmutableClass(FilterClause, [
testImmutableClass<FilterClauseJS>(FilterClause, [
{
expression: { op: 'ref', name: 'language' },
values: {
Expand Down
4 changes: 2 additions & 2 deletions src/common/models/filter/filter.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { Filter } from "./filter";
import { Filter, FilterJS } from "./filter";

describe('Filter', () => {
it('is an immutable class', () => {
testImmutableClass(Filter, [
testImmutableClass<FilterJS>(Filter, [
{ op: 'literal', value: true },
{
"op": "chain", "expression": { "op": "ref", "name": "language" },
Expand Down
4 changes: 2 additions & 2 deletions src/common/models/highlight/highlight.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { Highlight } from './highlight';
import { Highlight, HighlightJS } from './highlight';

describe('Highlight', () => {
it('is an immutable class', () => {
testImmutableClass(Highlight, [
testImmutableClass<HighlightJS>(Highlight, [
{
owner: 'Sunkist',
delta: {
Expand Down
4 changes: 2 additions & 2 deletions src/common/models/max-time/max-time.mocha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { expect } from 'chai';
import { testImmutableClass } from 'immutable-class/build/tester';

import { $, Expression } from 'plywood';
import { MaxTime } from './max-time';
import { MaxTime, MaxTimeJS } from './max-time';

describe('MaxTime', () => {
it('is an immutable class', () => {
testImmutableClass(MaxTime, [
testImmutableClass<MaxTimeJS>(MaxTime, [
{
time: new Date("2015-10-15T19:20:00Z"),
updated: new Date("2015-10-15T19:20:13Z")
Expand Down
Loading

0 comments on commit 906e453

Please sign in to comment.