├── monoid-py
├── py.typed
├── monoid_pydev
│ ├── __init__.py
│ ├── models
│ │ └── __init__.py
│ ├── utils
│ │ ├── __init__.py
│ │ └── utils.py
│ ├── logger
│ │ ├── __init__.py
│ │ └── logger.py
│ └── silos
│ │ └── __init__.py
├── mypy.ini
├── Makefile
├── README.md
├── requirements.txt
├── LICENSE
└── pyproject.toml
├── docusaurus
├── static
│ ├── .nojekyll
│ └── img
│ │ ├── favicon.ico
│ │ └── docusaurus.png
├── .gitignore
├── babel.config.js
├── blog
│ ├── 2021-08-26-welcome
│ │ ├── docusaurus-plushie-banner.jpeg
│ │ └── index.md
│ ├── 2019-05-28-first-blog-post.md
│ ├── authors.yml
│ └── 2021-08-01-mdx-blog-post.mdx
├── sidebars.js
├── README.md
├── package.json
└── src
│ └── css
│ └── custom.css
├── monoid-api
├── .dockerignore
├── .gitignore
├── config-data
│ ├── init.sql
│ ├── temporal
│ │ └── development-sql.yaml
│ ├── resources
│ │ └── images
│ │ │ ├── index.html
│ │ │ ├── redshift.svg
│ │ │ ├── intercom.svg
│ │ │ ├── mixpanel.svg
│ │ │ └── bigquery.svg
│ └── data-categories.yaml
├── workflow
│ ├── queues.go
│ ├── types.go
│ ├── activity
│ │ ├── types.go
│ │ ├── requestactivity
│ │ │ ├── types.go
│ │ │ ├── find_request.go
│ │ │ └── db_updates.go
│ │ └── helpers.go
│ ├── requestworkflow
│ │ └── types.go
│ └── validate_ds.go
├── model
│ ├── registration.go
│ ├── jobs.go
│ └── workspace.go
├── resolver
│ ├── resolver.go
│ └── silo_definition_helpers.go
├── tools.go
├── Dockerfile.dev
├── scanner
│ ├── scanner.go
│ ├── types.go
│ └── basicscanner
│ │ ├── types.go
│ │ └── helpers.go
├── analytics
│ ├── ingestor
│ │ └── ingestor.go
│ └── handlers.go
├── cmd
│ ├── worker
│ │ ├── Dockerfile
│ │ ├── .air.toml
│ │ ├── main.go
│ │ └── worker
│ │ │ └── worker.go
│ ├── server
│ │ ├── Dockerfile
│ │ └── .air.toml
│ ├── tools
│ │ ├── loader
│ │ │ ├── Dockerfile
│ │ │ └── main.go
│ │ └── discovery
│ │ │ └── main.go
│ └── analytics
│ │ └── main.go
├── monoidprotocol
│ └── docker
│ │ └── factory.go
├── Makefile
├── specimport
│ ├── types.go
│ └── tools.go
├── filestore
│ ├── filestore.go
│ ├── localstore
│ │ └── localstore.go
│ └── encryptedstore
│ │ └── encryptedstore.go
├── dataloader
│ ├── jobs.go
│ ├── silo_specifications.go
│ ├── query_results.go
│ ├── data_sources.go
│ └── silo_definitions.go
├── .golangci.yml
├── schema
│ ├── jobs.graphqls
│ ├── silo_definitions.graphqls
│ └── base.graphqls
├── requests
│ └── types.go
├── download
│ └── handlers.go
└── config
│ └── config.go
├── monoid-ui
├── .nvmrc
├── .dockerignore
├── src
│ ├── __generated__
│ │ └── index.ts
│ ├── react-app-env.d.ts
│ ├── index.css
│ ├── components
│ │ ├── nav
│ │ │ └── types.ts
│ │ ├── PageCenter.tsx
│ │ ├── Select.tsx
│ │ ├── BorderedRegion.tsx
│ │ ├── Divider.tsx
│ │ ├── SVGText.tsx
│ │ ├── Headers.tsx
│ │ ├── Empty.tsx
│ │ ├── Link.tsx
│ │ ├── MonoidLink.tsx
│ │ ├── ToastDisplayer.tsx
│ │ ├── Checkbox.tsx
│ │ ├── Input.tsx
│ │ ├── Breadcrumb.tsx
│ │ ├── Text.tsx
│ │ ├── Spinner.tsx
│ │ ├── Card.tsx
│ │ ├── PageHeader.tsx
│ │ └── Toggle.tsx
│ ├── lib
│ │ └── types.ts
│ ├── setupTests.ts
│ ├── common
│ │ └── LoadingPage.tsx
│ ├── App.test.tsx
│ ├── cache
│ │ ├── requests.ts
│ │ ├── dataMap.ts
│ │ ├── jobs.ts
│ │ ├── discoveries.ts
│ │ ├── requestStatus.ts
│ │ ├── config.ts
│ │ └── helpers.ts
│ ├── contexts
│ │ ├── ToastContext.tsx
│ │ └── WorkspaceContext.tsx
│ ├── pages
│ │ ├── Dashboard
│ │ │ └── DashboardPage.tsx
│ │ ├── Identifiers
│ │ │ ├── IdentifierRoutes.tsx
│ │ │ └── pages
│ │ │ │ └── NewPrimaryKeyPage
│ │ │ │ └── NewPrimaryKeyPage.tsx
│ │ ├── Silos
│ │ │ ├── pages
│ │ │ │ ├── SiloIndexPage
│ │ │ │ │ └── SiloIndex.tsx
│ │ │ │ ├── NewSiloPage
│ │ │ │ │ └── NewSiloPage.tsx
│ │ │ │ └── SiloPage
│ │ │ │ │ └── components
│ │ │ │ │ ├── PropertyCategoryCombobox.tsx
│ │ │ │ │ └── CategoryBadge.tsx
│ │ │ └── SiloRoutes.tsx
│ │ ├── Requests
│ │ │ ├── pages
│ │ │ │ ├── RequestIndexPage
│ │ │ │ │ └── RequestIndex.tsx
│ │ │ │ └── NewRequestPage
│ │ │ │ │ └── NewRequestPage.tsx
│ │ │ └── RequestRoutes.tsx
│ │ └── Onboarding
│ │ │ ├── WorkspaceAutoSelect.tsx
│ │ │ └── components
│ │ │ └── RequestStepBody.tsx
│ ├── reportWebVitals.ts
│ ├── index.tsx
│ ├── App.css
│ ├── App.tsx
│ ├── graphql
│ │ ├── requests_queries.ts
│ │ ├── silo_queries.ts
│ │ └── jobs_queries.ts
│ ├── hooks
│ │ └── useQueryPatched.tsx
│ └── utils
│ │ └── use-popper.ts
├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── logo192.png
│ ├── logo512.png
│ └── manifest.json
├── .vscode
│ └── settings.json
├── postcss.config.js
├── Dockerfile.dev
├── nginx
│ └── default.conf
├── tailwind.config.js
├── Dockerfile
├── .gitignore
├── tsconfig.json
├── codegen.ts
└── .eslintrc.js
├── monoid-integrations
├── monoid-intercom
│ ├── intercom
│ │ ├── __init__.py
│ │ ├── spec.json
│ │ └── intercom_silo.py
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ └── requirements.txt
├── monoid-mariadb
│ ├── mariadb_lib
│ │ ├── __init__.py
│ │ └── spec.json
│ ├── Makefile
│ ├── Dockerfile
│ ├── main.py
│ └── requirements.txt
├── monoid-mixpanel
│ ├── mixpanel
│ │ └── __init__.py
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ └── requirements.txt
├── monoid-mysql
│ ├── mysql_lib
│ │ ├── __init__.py
│ │ └── spec.json
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ └── requirements.txt
├── monoid-postgres
│ ├── postgres
│ │ ├── __init__.py
│ │ └── helpers.py
│ ├── .dockerignore
│ ├── mypy.ini
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ ├── requirements.txt
│ └── requirements.dev.txt
├── monoid-bigquery
│ ├── bigquery_lib
│ │ ├── __init__.py
│ │ ├── helpers.py
│ │ └── spec.json
│ ├── mypy.ini
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ ├── requirements.txt
│ └── requirements.dev.txt
├── monoid-redshift
│ ├── redshift_lib
│ │ ├── __init__.py
│ │ └── helpers.py
│ ├── mypy.ini
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ ├── requirements.txt
│ └── requirements.dev.txt
├── monoid-snowflake
│ ├── snowflake_lib
│ │ ├── __init__.py
│ │ └── helpers.py
│ ├── mypy.ini
│ ├── Dockerfile
│ ├── Makefile
│ ├── main.py
│ ├── snowflake_requirements.txt
│ └── requirements.txt
└── Makefile
├── .dockerignore
├── .gitignore
├── docs
├── img
│ ├── alerts.png
│ ├── mysql-silo.png
│ ├── bigquery-silo.png
│ ├── find-snowflake.png
│ ├── postgres-silo.png
│ ├── redshift-silo.png
│ ├── scheduled-scans.png
│ ├── snowflake-silo.png
│ └── user-identifier.png
├── monoid-cloud
│ ├── _category_.json
│ └── overview.md
├── understand
│ ├── _category_.json
│ └── technical
│ │ ├── _category_.json
│ │ └── architecture-overview.md
├── deploy-monoid-open-source
│ ├── gcp.md
│ ├── azure.md
│ ├── _category_.json
│ ├── local.md
│ └── aws.md
├── connector-catalog
│ ├── _category_.json
│ ├── data-silo-guides
│ │ ├── _category_.json
│ │ ├── mysql.md
│ │ ├── postgres.md
│ │ ├── redshift.md
│ │ ├── snowflake.md
│ │ └── bigquery.md
│ ├── overview.md
│ └── connector-list.md
├── contribute-to-monoid
│ └── _category_.json
├── monoid-open-source-quick-start
│ ├── _category_.json
│ ├── deploy-monoid.md
│ ├── create-user-identifiers.md
│ ├── connect-data-silos.md
│ ├── create-data-map.md
│ └── scan-data-sources.md
├── build-a-connector
│ └── _category_.json
├── project-overview
│ ├── _category_.json
│ └── roadmap.md
└── start-here.md
├── monoid-proxy
├── Dockerfile
└── default.conf
├── connector-testing-ui
├── client
│ ├── public
│ │ ├── robots.txt
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ └── manifest.json
│ ├── src
│ │ ├── setupTests.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── reportWebVitals.js
│ │ ├── index.js
│ │ └── App.css
│ ├── .gitignore
│ └── package.json
├── server
│ └── .gitignore
├── .gitignore
└── README.md
├── .vscode
└── settings.json
├── monoid-codescan
├── .gitignore
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── config
│ ├── sinks
│ │ ├── storage
│ │ │ ├── go
│ │ │ │ └── gorm.yaml
│ │ │ └── java
│ │ │ │ └── jpa.yaml
│ │ ├── sdk
│ │ │ ├── java
│ │ │ │ ├── segment
│ │ │ │ │ ├── segment.yaml
│ │ │ │ │ └── ignore.yaml
│ │ │ │ └── spring
│ │ │ │ │ └── ignore.yaml
│ │ │ └── go
│ │ │ │ └── logging.yaml
│ │ └── builtin
│ │ │ ├── java
│ │ │ ├── ignored.yaml
│ │ │ └── logging.yaml
│ │ │ └── go
│ │ │ ├── ignored.yaml
│ │ │ └── logging.yaml
│ └── sources
│ │ └── user.yaml
├── app
│ └── src
│ │ ├── main
│ │ ├── resources
│ │ │ └── queries
│ │ │ │ ├── CreateCodescanRepo.graphql
│ │ │ │ └── CreateCodescanResult.graphql
│ │ └── kotlin
│ │ │ └── monoid
│ │ │ └── codescan
│ │ │ ├── output
│ │ │ └── PrintHelpers.kt
│ │ │ ├── Extension.kt
│ │ │ └── config
│ │ │ └── CodescanConfig.kt
│ │ └── test
│ │ └── kotlin
│ │ └── monoid
│ │ └── codescan
│ │ └── AppTest.kt
├── .gitattributes
├── settings.gradle.kts
└── README.md
├── .github
└── workflows
│ ├── docker-build.yml
│ ├── js-lint.yml
│ ├── backend-test.yml
│ ├── integrations-push.yml
│ ├── go-lint.yml
│ └── docker-push.yml
├── .env.dev
├── .env
├── docker-compose.build.yaml
├── Makefile
└── LICENSE
/monoid-py/py.typed:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docusaurus/static/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-api/.dockerignore:
--------------------------------------------------------------------------------
1 | .env
2 |
--------------------------------------------------------------------------------
/monoid-api/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 |
--------------------------------------------------------------------------------
/monoid-ui/.nvmrc:
--------------------------------------------------------------------------------
1 | v18.12.1
2 |
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-py/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | exclude = venv
3 |
--------------------------------------------------------------------------------
/monoid-ui/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 |
--------------------------------------------------------------------------------
/monoid-api/config-data/init.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE monoid;
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/intercom/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mariadb/mariadb_lib/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mixpanel/mixpanel/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mysql/mysql_lib/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/postgres/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docusaurus/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | node_modules/
3 | .docusaurus/
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/bigquery_lib/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/redshift_lib/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/snowflake_lib/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-ui/src/__generated__/index.ts:
--------------------------------------------------------------------------------
1 | export * from './gql';
2 |
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/models/__init__.py:
--------------------------------------------------------------------------------
1 | from .models import *
2 |
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .utils import *
2 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/.dockerignore:
--------------------------------------------------------------------------------
1 | venv
2 | secrets
3 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | monoid-api/
2 | monoid-ui/
3 | docusaurus/
4 | ./**/venv
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | secrets/
2 | .DS_Store
3 | tmp/
4 | monoid-filestore/
5 | bin
6 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | exclude = venv
3 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | exclude = venv
3 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | exclude = venv
3 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | exclude = venv
3 |
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/logger/__init__.py:
--------------------------------------------------------------------------------
1 | from .logger import get_logger
2 |
--------------------------------------------------------------------------------
/monoid-ui/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 |
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/silos/__init__.py:
--------------------------------------------------------------------------------
1 | from .abstract_silo import AbstractSilo
2 |
--------------------------------------------------------------------------------
/monoid-py/Makefile:
--------------------------------------------------------------------------------
1 | dist:
2 | python -m build
3 | push: dist
4 | twine upload dist/*
5 |
--------------------------------------------------------------------------------
/monoid-ui/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/docs/img/alerts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/alerts.png
--------------------------------------------------------------------------------
/docs/img/mysql-silo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/mysql-silo.png
--------------------------------------------------------------------------------
/monoid-api/workflow/queues.go:
--------------------------------------------------------------------------------
1 | package workflow
2 |
3 | const DockerRunnerQueue = "DOCKER_RUNNER_QUEUE"
4 |
--------------------------------------------------------------------------------
/monoid-proxy/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginx:1.23-alpine
2 | COPY ./default.conf /etc/nginx/conf.d/default.conf
3 |
--------------------------------------------------------------------------------
/monoid-ui/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/docs/img/bigquery-silo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/bigquery-silo.png
--------------------------------------------------------------------------------
/docs/img/find-snowflake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/find-snowflake.png
--------------------------------------------------------------------------------
/docs/img/postgres-silo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/postgres-silo.png
--------------------------------------------------------------------------------
/docs/img/redshift-silo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/redshift-silo.png
--------------------------------------------------------------------------------
/docs/img/scheduled-scans.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/scheduled-scans.png
--------------------------------------------------------------------------------
/docs/img/snowflake-silo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/snowflake-silo.png
--------------------------------------------------------------------------------
/docs/img/user-identifier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docs/img/user-identifier.png
--------------------------------------------------------------------------------
/monoid-api/model/registration.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type OSSRegistration struct {
4 | ID string
5 | }
6 |
--------------------------------------------------------------------------------
/monoid-ui/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/monoid-ui/public/favicon.ico
--------------------------------------------------------------------------------
/monoid-ui/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/monoid-ui/public/logo192.png
--------------------------------------------------------------------------------
/monoid-ui/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/monoid-ui/public/logo512.png
--------------------------------------------------------------------------------
/docusaurus/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docusaurus/static/img/favicon.ico
--------------------------------------------------------------------------------
/connector-testing-ui/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/docusaurus/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3 | };
4 |
--------------------------------------------------------------------------------
/monoid-ui/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll.eslint": true
4 | }
5 | }
--------------------------------------------------------------------------------
/docusaurus/static/img/docusaurus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docusaurus/static/img/docusaurus.png
--------------------------------------------------------------------------------
/monoid-ui/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.packageManager": "yarn",
3 | "eslint.workingDirectories": [
4 | "./monoid-ui",
5 | ]
6 | }
--------------------------------------------------------------------------------
/monoid-py/README.md:
--------------------------------------------------------------------------------
1 | # Monoid Integration Tools
2 | This package includes the tools required to build a new data silo for
3 | the Monoid Platform.
--------------------------------------------------------------------------------
/connector-testing-ui/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/connector-testing-ui/client/public/favicon.ico
--------------------------------------------------------------------------------
/connector-testing-ui/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/connector-testing-ui/client/public/logo192.png
--------------------------------------------------------------------------------
/connector-testing-ui/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/connector-testing-ui/client/public/logo512.png
--------------------------------------------------------------------------------
/monoid-codescan/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore Gradle project-specific cache directory
2 | .gradle
3 |
4 | # Ignore Gradle build output directory
5 | build
6 |
--------------------------------------------------------------------------------
/monoid-codescan/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/monoid-codescan/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/monoid-api/workflow/types.go:
--------------------------------------------------------------------------------
1 | package workflow
2 |
3 | import "github.com/monoid-privacy/monoid/config"
4 |
5 | type Workflow struct {
6 | Conf *config.BaseConfig
7 | }
8 |
--------------------------------------------------------------------------------
/monoid-api/workflow/activity/types.go:
--------------------------------------------------------------------------------
1 | package activity
2 |
3 | import "github.com/monoid-privacy/monoid/config"
4 |
5 | type Activity struct {
6 | Conf *config.BaseConfig
7 | }
8 |
--------------------------------------------------------------------------------
/docusaurus/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monoid-privacy/monoid/HEAD/docusaurus/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | ENTRYPOINT [ "python", "main.py" ]
6 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | ENTRYPOINT [ "python", "main.py" ]
6 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mixpanel/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | ENTRYPOINT [ "python", "main.py" ]
6 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mysql/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | ENTRYPOINT [ "python", "main.py" ]
6 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | ENTRYPOINT [ "python", "main.py" ]
6 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | ENTRYPOINT [ "python", "main.py" ]
6 |
--------------------------------------------------------------------------------
/monoid-ui/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM node:16-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY ./package.json .
6 | RUN yarn install
7 |
8 | EXPOSE 3000
9 | ENTRYPOINT ["yarn", "run", "start"]
10 |
--------------------------------------------------------------------------------
/monoid-api/resolver/resolver.go:
--------------------------------------------------------------------------------
1 | package resolver
2 |
3 | import (
4 | "github.com/monoid-privacy/monoid/config"
5 | )
6 |
7 | type Resolver struct {
8 | Conf *config.BaseConfig
9 | }
10 |
--------------------------------------------------------------------------------
/monoid-api/workflow/requestworkflow/types.go:
--------------------------------------------------------------------------------
1 | package requestworkflow
2 |
3 | import "github.com/monoid-privacy/monoid/config"
4 |
5 | type RequestWorkflow struct {
6 | Conf *config.BaseConfig
7 | }
8 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/storage/go/gorm.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: gorm
2 | languages:
3 | - go
4 | rules:
5 | - id: gorm
6 | name: DB Write (GORM)
7 | regex: ^gorm.io/gorm.DB.(?:Create|Update|Updates)$
--------------------------------------------------------------------------------
/docs/monoid-cloud/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Monoid Cloud",
3 | "position": 3,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "A guide to Monoid's cloud offering."}
7 | }
8 |
--------------------------------------------------------------------------------
/monoid-api/tools.go:
--------------------------------------------------------------------------------
1 | //go:build tools
2 | // +build tools
3 |
4 | package tools
5 |
6 | import (
7 | _ "github.com/99designs/gqlgen"
8 | _ "github.com/99designs/gqlgen/graphql/introspection"
9 | )
10 |
--------------------------------------------------------------------------------
/monoid-codescan/app/src/main/resources/queries/CreateCodescanRepo.graphql:
--------------------------------------------------------------------------------
1 | mutation CreateCodescanRepo($input: CreateCodescanRepoInput!) {
2 | createCodescanRepo(input: $input) {
3 | id
4 | }
5 | }
--------------------------------------------------------------------------------
/monoid-ui/src/components/nav/types.ts:
--------------------------------------------------------------------------------
1 | export interface NavLink {
2 | title: React.ReactNode
3 | onClick: () => void
4 | current: boolean
5 | icon?: (props?: any) => JSX.Element
6 | key: string
7 | }
8 |
--------------------------------------------------------------------------------
/monoid-api/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM golang:1.18-alpine
2 |
3 | WORKDIR /app
4 |
5 | RUN go install github.com/cosmtrek/air@latest
6 |
7 | COPY go.mod go.sum ./
8 | RUN go mod download
9 |
10 | ENTRYPOINT ["air"]
--------------------------------------------------------------------------------
/monoid-api/config-data/temporal/development-sql.yaml:
--------------------------------------------------------------------------------
1 | limit.maxIDLength:
2 | - value: 255
3 | constraints: {}
4 | system.forceSearchAttributesCacheRefreshOnRead:
5 | - value: false
6 | constraints: {}
7 |
--------------------------------------------------------------------------------
/monoid-ui/nginx/default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | location / {
4 | root /usr/share/nginx/html;
5 | index index.html;
6 | try_files $uri $uri/ /index.html =404;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/connector-testing-ui/server/.gitignore:
--------------------------------------------------------------------------------
1 | # ignore secrets and tmp directories
2 | secrets/
3 | tmp/
4 |
5 | # ignore Python bytecode files
6 | *.pyc
7 | __pycache__/
8 |
9 | # ignore log files
10 | *.log
11 |
12 |
--------------------------------------------------------------------------------
/docs/understand/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Understand Monoid",
3 | "position": 9,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "An in-depth look at how Monoid works."
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/sdk/java/segment/segment.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: segment
2 | languages:
3 | - java
4 | rules:
5 | - id: segment
6 | name: Segment
7 | regex: ^(?:com.segment.analytics.Analytics)\.(?:enqueue)
--------------------------------------------------------------------------------
/docs/deploy-monoid-open-source/gcp.md:
--------------------------------------------------------------------------------
1 | # GCP
2 |
3 | GCP deployment instructions and one-click deploy for GCP will be available soon. In the meantime, please [reach out to us](mailto:vignesh@monoid.co) and we'll get you set up.
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/builtin/java/ignored.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: java-system
2 | languages:
3 | - java
4 | action: ignore
5 | rules:
6 | - id: java_system_libraries
7 | name: System Libraries
8 | regex: ^(?i)java\..*
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/sdk/go/logging.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: logging
2 | languages:
3 | - go
4 | action: ignore
5 | rules:
6 | - id: zerolog
7 | name: Logging (Zerolog)
8 | regex: ^(?i)github.com/rs/zerolog.Event.Msg
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/utils/utils.py:
--------------------------------------------------------------------------------
1 | import pkgutil
2 | from typing import Optional
3 |
4 |
5 | def load_package_file(package: str, file_name: str) -> Optional[bytes]:
6 | return pkgutil.get_data(package, file_name)
7 |
--------------------------------------------------------------------------------
/docs/deploy-monoid-open-source/azure.md:
--------------------------------------------------------------------------------
1 | # Azure
2 |
3 | Azure deployment instructions and one-click deploy for Azure will be available soon. In the meantime, please [reach out to us](mailto:vignesh@monoid.co) and we'll get you set up.
--------------------------------------------------------------------------------
/monoid-api/workflow/activity/requestactivity/types.go:
--------------------------------------------------------------------------------
1 | package requestactivity
2 |
3 | import (
4 | "github.com/monoid-privacy/monoid/config"
5 | )
6 |
7 | type RequestActivity struct {
8 | Conf *config.BaseConfig
9 | }
10 |
--------------------------------------------------------------------------------
/docs/understand/technical/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Technical Guide",
3 | "position": 2,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "An in-depth technical look at how Monoid works."
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install -r requirements.txt
5 | RUN pip3 install -r snowflake_requirements.txt
6 | ENTRYPOINT [ "python", "main.py" ]
7 |
--------------------------------------------------------------------------------
/docs/connector-catalog/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Connector Catalog",
3 | "position": 2,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "A catalog of pre-built open-source Monoid connectors."
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/docs/contribute-to-monoid/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Contribute to Monoid",
3 | "position": 8,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "A guide to contributing to Monoid Open Source."
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/docs/deploy-monoid-open-source/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Deploy Monoid Open Source",
3 | "position": 5,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "A guide to deploying Monoid Open Source."
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mysql/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-mysql'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-api/scanner/scanner.go:
--------------------------------------------------------------------------------
1 | package scanner
2 |
3 | import (
4 | "github.com/monoid-privacy/monoid/monoidprotocol"
5 | )
6 |
7 | type Scanner interface {
8 | Scan(*monoidprotocol.MonoidRecord) error
9 | Summary() []RuleMatch
10 | }
11 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-bigquery'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-intercom'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mariadb/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-mariadb'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mixpanel/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-mixpanel'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-postgres'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-redshift'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/Makefile:
--------------------------------------------------------------------------------
1 | IMAGE_NAME := 'monoidco/monoid-snowflake'
2 | IMAGE_VERSION := '0.0.1'
3 |
4 | build:
5 | docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION}
6 |
7 | push:
8 | docker push ${IMAGE_NAME}:${IMAGE_VERSION}
9 |
--------------------------------------------------------------------------------
/monoid-ui/src/lib/types.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import { JSONSchema7 } from 'json-schema';
3 |
4 | export interface MonoidJSONSchema extends JSONSchema7 {
5 | order?: number,
6 | secret?: boolean
7 | }
8 |
--------------------------------------------------------------------------------
/docs/deploy-monoid-open-source/local.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | sidebar_label: "Locally"
4 | ---
5 |
6 | # Deploy Monoid Open Source Locally
7 |
8 | See the [Monoid Open-Source QuickStart Guide](/monoid-open-source-quick-start/deploy-monoid.md).
9 |
--------------------------------------------------------------------------------
/docs/monoid-open-source-quick-start/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Monoid Open Source Quick Start",
3 | "position": 4,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "A guide to getting started with Monoid open source."}
7 | }
8 |
--------------------------------------------------------------------------------
/docs/deploy-monoid-open-source/aws.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2
3 | ---
4 | # AWS
5 |
6 | AWS deployment instructions and one-click deploy for AWS will be available soon. In the meantime, please [reach out to us](mailto:vignesh@monoid.co) and we'll get you set up.
--------------------------------------------------------------------------------
/monoid-codescan/app/src/main/resources/queries/CreateCodescanResult.graphql:
--------------------------------------------------------------------------------
1 | mutation CreateCodescanResult($input: CreateCodescanResultInput!) {
2 | createCodescanResult(input: $input) {
3 | codescanRepo {
4 | id
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/builtin/go/ignored.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: system
2 | languages:
3 | - go
4 | action: ignore
5 | rules:
6 | - id: system_libraries
7 | name: System Libraries
8 | regex: ^(?i)encoding/json|sync|strconv|net/http|context|os|bytes|io|path
--------------------------------------------------------------------------------
/docs/connector-catalog/data-silo-guides/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Data Silo Connector Guides",
3 | "position": 2,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "Guides for setting up each Monoid pre-built connector."
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/monoid-api/analytics/ingestor/ingestor.go:
--------------------------------------------------------------------------------
1 | package ingestor
2 |
3 | type Ingestor interface {
4 | Identify(userID *string, traits map[string]interface{}) error
5 | Track(event string, userID *string, properties map[string]interface{}) error
6 | Close() error
7 | }
8 |
--------------------------------------------------------------------------------
/docs/build-a-connector/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Build a Connector",
3 | "position": 7,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "A guide to building a new Monoid connector, for
7 | private or public use."
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/docs/project-overview/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "Project Overview",
3 | "position": 7,
4 | "link": {
5 | "type": "generated-index",
6 | "description": "Details about the Monoid Open Source project, including our
7 | mission and roadmap."
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/sdk/java/segment/ignore.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: segment_ignore
2 | action: ignore
3 | languages:
4 | - java
5 | rules:
6 | - id: segment_ignore
7 | name: Segment Ignore
8 | regex: ^(?:com.segment.analytics)\.(?:messages.IdentifyMessage|Analytics.builder)
--------------------------------------------------------------------------------
/monoid-ui/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/monoid-codescan/.gitattributes:
--------------------------------------------------------------------------------
1 | #
2 | # https://help.github.com/articles/dealing-with-line-endings/
3 | #
4 | # Linux start script should use lf
5 | /gradlew text eol=lf
6 |
7 | # These are Windows script files and should use crlf
8 | *.bat text eol=crlf
9 |
10 |
--------------------------------------------------------------------------------
/monoid-codescan/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
4 | networkTimeout=10000
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/.github/workflows/docker-build.yml:
--------------------------------------------------------------------------------
1 | name: Build Core Docker Images
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 | - name: Build Core
11 | run: make docker-build docker-build-codescan
12 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 |
4 | # production
5 | build
6 |
7 | # misc
8 | .DS_Store
9 | .env.local
10 | .env.development.local
11 | .env.test.local
12 | .env.production.local
13 |
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
18 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mysql/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from mysql_lib.mysql_silo import MySQLSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = MySQLSilo()
9 | run_query(integration, sys.argv[1:])
10 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mariadb/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim-buster
2 | WORKDIR /app
3 | COPY . .
4 | RUN pip3 install --upgrade pip
5 | RUN pip3 install packaging
6 | RUN apt-get update; apt-get install -y libmariadb-dev gcc
7 | RUN pip3 install -r requirements.txt
8 | ENTRYPOINT [ "python", "main.py" ]
9 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from intercom.intercom_silo import IntercomSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = IntercomSilo()
9 | run_query(integration, sys.argv[1:])
10 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mariadb/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from mariadb_lib.mariadb_silo import MariaDBSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = MariaDBSilo()
9 | run_query(integration, sys.argv[1:])
10 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mixpanel/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from mixpanel.mixpanel_silo import MixpanelSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = MixpanelSilo()
9 | run_query(integration, sys.argv[1:])
10 |
--------------------------------------------------------------------------------
/monoid-ui/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | './public/index.html',
5 | "./src/**/*.{js,jsx,ts,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [
11 | require('@tailwindcss/forms'),
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/monoid-ui/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16-alpine
2 |
3 | COPY . /app
4 | WORKDIR /app
5 |
6 | RUN yarn install
7 | RUN yarn run build
8 |
9 | FROM nginx:1.23-alpine
10 |
11 | COPY --from=0 /app/build /usr/share/nginx/html
12 | COPY --from=0 /app/nginx/default.conf /etc/nginx/conf.d/default.conf
13 |
14 | EXPOSE 80
15 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/sdk/java/spring/ignore.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: spring_ignore
2 | action: ignore
3 | languages:
4 | - java
5 | rules:
6 | - id: web
7 | name: Web
8 | regex: ^(?:org.springframework)\.(?:web|validation|util|samples)
9 | - id: unk
10 | name: Unknown
11 | regex: ^(?:UNKNOWN|T|Pet)\..*
--------------------------------------------------------------------------------
/monoid-api/cmd/worker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.18-alpine AS build
2 | COPY . /app
3 | WORKDIR /app
4 | RUN go mod download
5 | RUN go build -o worker ./cmd/worker/main.go
6 |
7 | FROM alpine:3.14
8 | WORKDIR /app
9 | COPY --from=build /app/worker worker
10 | COPY --from=build /app/config-data config-data
11 | CMD [ "./worker" ]
--------------------------------------------------------------------------------
/monoid-ui/src/common/LoadingPage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PageCenter from '../components/PageCenter';
3 | import Spinner from '../components/Spinner';
4 |
5 | export default function LoadingPage() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/builtin/go/logging.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: logging
2 | languages:
3 | - go
4 | rules:
5 | - id: log
6 | name: Logging
7 | regex: ^(?:log|log.Logger).(?:Fatal|Fatalf|Fatalln|Panic|Panicf|Panicln|Print|Println|Printf)$
8 | - id: print
9 | name: Print
10 | regex: ^fmt\.(?:Println|Printf)
11 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/storage/java/jpa.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: jpa
2 | languages:
3 | - java
4 | rules:
5 | - id: jpa_write
6 | name: DB Write (JPA)
7 | regex: ^jakarta.persistence.EntityManager.(?:persist|merge)$
8 | - id: jpa_read
9 | name: DB Read (JPA)
10 | regex: ^jakarta.persistence.EntityManager.(?:find)$
--------------------------------------------------------------------------------
/monoid-api/cmd/server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.18-alpine AS build
2 | COPY . /app
3 | WORKDIR /app
4 | RUN go mod download
5 | RUN go build -o server ./cmd/server/main.go
6 |
7 | FROM alpine:3.14
8 | WORKDIR /app
9 | COPY --from=build /app/server server
10 | COPY --from=build /app/config-data config-data
11 |
12 | CMD [ "./server" ]
--------------------------------------------------------------------------------
/monoid-ui/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sinks/builtin/java/logging.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: logging
2 | languages:
3 | - java
4 | rules:
5 | - id: print
6 | name: Print
7 | regex: ^(?:java.io.PrintStream).(?:print|println)$
8 | - id: logging
9 | name: Logging
10 | regex: ^(?:java.util.logging.Logger)\.(?:log|info|warning|error|severe|throwing)
11 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from postgres.postgres_silo import PostgresSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = PostgresSilo()
9 | run_query(integration, sys.argv[1:])
10 | integration.teardown()
11 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from bigquery_lib.bigquery_silo import BigQuerySilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = BigQuerySilo()
9 | run_query(integration, sys.argv[1:])
10 | integration.teardown()
11 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from redshift_lib.redshift_silo import RedshiftSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = RedshiftSilo()
9 | run_query(integration, sys.argv[1:])
10 | integration.teardown()
11 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from sys import argv
3 | import sys
4 | from snowflake_lib.snowflake_silo import SnowflakeSilo
5 | from monoid_pydev.runner import run_query
6 |
7 | if __name__ == "__main__":
8 | integration = SnowflakeSilo()
9 | run_query(integration, sys.argv[1:])
10 | integration.teardown()
11 |
--------------------------------------------------------------------------------
/monoid-ui/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 | /.pnp
4 | .pnp.js
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
23 | .env
24 |
--------------------------------------------------------------------------------
/monoid-codescan/app/src/test/kotlin/monoid/codescan/AppTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * This Kotlin source file was generated by the Gradle 'init' task.
3 | */
4 | package monoid.codescan
5 |
6 | import kotlin.test.Test
7 | import kotlin.test.assertNotNull
8 |
9 | class AppTest {
10 | @Test fun appHasAGreeting() {
11 | val classUnderTest = App()
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.github/workflows/js-lint.yml:
--------------------------------------------------------------------------------
1 | name: JS Lint
2 | on: push
3 | jobs:
4 | build:
5 | runs-on: ubuntu-latest
6 | defaults:
7 | run:
8 | working-directory: ./monoid-ui
9 | steps:
10 | - uses: actions/checkout@v2
11 | - name: Install modules
12 | run: yarn
13 | - name: Run ESLint
14 | run: yarn run eslint . --ext .js,.jsx,.ts,.tsx
15 |
--------------------------------------------------------------------------------
/monoid-api/workflow/activity/helpers.go:
--------------------------------------------------------------------------------
1 | package activity
2 |
3 | type DataSourceMatcher struct {
4 | Group string
5 | Name string
6 | }
7 |
8 | func NewDataSourceMatcher(name string, group *string) DataSourceMatcher {
9 | gr := ""
10 | if group != nil {
11 | gr = *group
12 | }
13 |
14 | return DataSourceMatcher{
15 | Name: name,
16 | Group: gr,
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/monoid-api/cmd/tools/loader/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.18-alpine AS build
2 | COPY . /app
3 | WORKDIR /app
4 | RUN go mod download
5 | RUN go build -o monoid-loader ./cmd/tools/loader/main.go
6 |
7 | FROM alpine:3.14
8 | WORKDIR /app
9 | COPY --from=build /app/monoid-loader monoid-loader
10 | COPY --from=build /app/config-data config-data
11 |
12 | ENTRYPOINT [ "./monoid-loader" ]
13 |
--------------------------------------------------------------------------------
/monoid-codescan/app/src/main/kotlin/monoid/codescan/output/PrintHelpers.kt:
--------------------------------------------------------------------------------
1 | package monoid.codescan.output
2 |
3 | import monoid.codescan.queries.NodePath
4 |
5 | fun NodePath.pathTrace(): String {
6 | val nodes = this.nodes
7 |
8 | return buildString {
9 | for (n in nodes) {
10 | append(n.code + " " + n::class + "(" + n.location + ")\n")
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/monoid-proxy/default.conf:
--------------------------------------------------------------------------------
1 | upstream web {
2 | server monoid-web:80;
3 | }
4 |
5 | upstream api {
6 | server monoid-api:8080;
7 | }
8 |
9 | server {
10 | listen 80;
11 |
12 | location / {
13 | proxy_pass http://web;
14 | }
15 |
16 | location /query {
17 | proxy_pass http://api;
18 | }
19 |
20 | location /downloads/ {
21 | proxy_pass http://api;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/monoid-api/config-data/resources/images/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-api/monoidprotocol/docker/factory.go:
--------------------------------------------------------------------------------
1 | package docker
2 |
3 | import "github.com/monoid-privacy/monoid/monoidprotocol"
4 |
5 | type DockerProtocolFactory struct{}
6 |
7 | func (d *DockerProtocolFactory) NewMonoidProtocol(
8 | dockerImage string, dockerTag string, persistDir string,
9 | ) (monoidprotocol.MonoidProtocol, error) {
10 | return NewDockerMP(dockerImage, dockerTag, persistDir)
11 | }
12 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/requests.ts:
--------------------------------------------------------------------------------
1 | import { FieldPolicy, FieldReadFunction } from '@apollo/client';
2 | import { paginationMerge, paginationRead } from './helpers';
3 |
4 | export default function requestsCache(): FieldPolicy | FieldReadFunction {
5 | return ({
6 | keyArgs: [],
7 | read: paginationRead('requests'),
8 | merge: paginationMerge('requests', 'numRequests'),
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/dataMap.ts:
--------------------------------------------------------------------------------
1 | import { FieldPolicy, FieldReadFunction } from '@apollo/client';
2 | import { paginationMerge, paginationRead } from './helpers';
3 |
4 | export default function dataMapCache(): FieldPolicy | FieldReadFunction {
5 | return ({
6 | keyArgs: ['query'],
7 | read: paginationRead('dataMapRows'),
8 | merge: paginationMerge('dataMapRows', 'numRows'),
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/.github/workflows/backend-test.yml:
--------------------------------------------------------------------------------
1 | name: Test Backend
2 |
3 | on: push
4 |
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 |
11 | - name: Set up Go
12 | uses: actions/setup-go@v2
13 | with:
14 | go-version: 1.18
15 |
16 | - name: Build
17 | run: make monoid-api/build
18 |
19 | - name: Test
20 | run: make monoid-api/test
21 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/jobs.ts:
--------------------------------------------------------------------------------
1 | import { FieldPolicy, FieldReadFunction } from '@apollo/client';
2 | import { paginationMerge, paginationRead } from './helpers';
3 |
4 | export default function jobsQueryCache(): FieldPolicy | FieldReadFunction {
5 | return ({
6 | keyArgs: ['resourceId', 'jobType', 'status', 'query'],
7 | read: paginationRead('jobs'),
8 | merge: paginationMerge('jobs', 'numJobs'),
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/connector-testing-ui/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/discoveries.ts:
--------------------------------------------------------------------------------
1 | import { FieldPolicy, FieldReadFunction } from '@apollo/client';
2 | import { paginationMerge, paginationRead } from './helpers';
3 |
4 | export default function discoveriesCache(): FieldPolicy | FieldReadFunction {
5 | return ({
6 | keyArgs: ['query', 'statuses'],
7 | read: paginationRead('discoveries'),
8 | merge: paginationMerge('discoveries', 'numDiscoveries'),
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/requestStatus.ts:
--------------------------------------------------------------------------------
1 | import { FieldPolicy, FieldReadFunction } from '@apollo/client';
2 | import { paginationMerge, paginationRead } from './helpers';
3 |
4 | export default function requestStatusCache(): FieldPolicy | FieldReadFunction {
5 | return ({
6 | keyArgs: ['query'],
7 | read: paginationRead('requestStatusRows'),
8 | merge: paginationMerge('requestStatusRows', 'numStatuses'),
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/monoid-api/Makefile:
--------------------------------------------------------------------------------
1 | BIN_DIR = bin
2 | .PHONY: bin/worker bin/loader bin/server bin/discovery
3 |
4 | test:
5 | go test ./...
6 |
7 | build: bin/worker bin/loader bin/server bin/discovery
8 |
9 | bin/worker:
10 | go build -o $@ cmd/worker/main.go
11 |
12 | bin/loader:
13 | go build -o $@ cmd/tools/loader/main.go
14 |
15 | bin/server:
16 | go build -o $@ cmd/server/main.go
17 |
18 | bin/discovery:
19 | go build -o $@ cmd/tools/discovery/main.go
20 |
--------------------------------------------------------------------------------
/monoid-codescan/config/sources/user.yaml:
--------------------------------------------------------------------------------
1 | ruleGroup: user
2 | rules:
3 | - name: Email
4 | regex: (?i)email
5 | id: email
6 | - name: First Name
7 | regex: (?i)first.*name
8 | id: first_name
9 | - name: Last Name
10 | regex: (?i)last.*name
11 | id: last_name
12 | - name: Full Name
13 | regex: (?i)(?!last|first).*name
14 | id: full_name
15 | - name: Phone Number
16 | regex: (?i)(?:tele)?phone
17 | id: phone_number
--------------------------------------------------------------------------------
/connector-testing-ui/client/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/snowflake_requirements.txt:
--------------------------------------------------------------------------------
1 | # Generated on: Python 3.9.15
2 | asn1crypto==1.5.1
3 | certifi==2022.9.24
4 | cffi==1.15.1
5 | charset-normalizer==2.1.1
6 | cryptography==38.0.3
7 | filelock==3.8.0
8 | idna==3.4
9 | oscrypto==1.3.0
10 | pycparser==2.21
11 | pycryptodomex==3.15.0
12 | PyJWT==2.6.0
13 | pyOpenSSL==22.1.0
14 | pytz==2022.6
15 | requests==2.28.1
16 | typing_extensions==4.4.0
17 | urllib3==1.26.12
18 | snowflake-connector-python==2.8.2
--------------------------------------------------------------------------------
/docusaurus/blog/2019-05-28-first-blog-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: first-blog-post
3 | title: First Blog Post
4 | authors:
5 | name: Gao Wei
6 | title: Docusaurus Core Team
7 | url: https://github.com/wgao19
8 | image_url: https://github.com/wgao19.png
9 | tags: [hola, docusaurus]
10 | ---
11 |
12 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
13 |
--------------------------------------------------------------------------------
/monoid-ui/src/contexts/ToastContext.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | interface ToastContextType {
4 | showToast: (v: {
5 | title: string,
6 | message: React.ReactNode,
7 | variant?: 'success' | 'danger',
8 | icon: (props: any) => React.ReactElement
9 | }) => void
10 | }
11 |
12 | const initValToast: ToastContextType = {
13 | showToast: () => {
14 | throw new Error('Unimplemented default');
15 | },
16 | };
17 |
18 | export default React.createContext(initValToast);
19 |
--------------------------------------------------------------------------------
/connector-testing-ui/README.md:
--------------------------------------------------------------------------------
1 | # Connector Testing UI
2 |
3 | This is a simple webapp for testing connector Docker containers. To use it, build you connector Docker image and enter the name at the top of the page, as well as each of the JSON's required for the various Docker commands.
4 |
5 | Build the client with ` cd client && yarn run build `
6 |
7 | Then run the server with ` cd server && python app.py `
8 |
9 | The server uses file storage: `secrets/` for the config files and `tmp/output.log` to store the output.
10 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Dashboard/DashboardPage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import AlertsCard from './components/AlertsCard';
3 | import RequestsCard from './components/RequestsCard';
4 | import ScansCard from './components/ScansCard';
5 |
6 | export default function DashboardPage() {
7 | return (
8 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/monoid-ui/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({
6 | getCLS, getFID, getFCP, getLCP, getTTFB,
7 | }) => {
8 | getCLS(onPerfEntry);
9 | getFID(onPerfEntry);
10 | getFCP(onPerfEntry);
11 | getLCP(onPerfEntry);
12 | getTTFB(onPerfEntry);
13 | });
14 | }
15 | };
16 |
17 | export default reportWebVitals;
18 |
--------------------------------------------------------------------------------
/docusaurus/blog/authors.yml:
--------------------------------------------------------------------------------
1 | endi:
2 | name: Endilie Yacop Sucipto
3 | title: Maintainer of Docusaurus
4 | url: https://github.com/endiliey
5 | image_url: https://github.com/endiliey.png
6 |
7 | yangshun:
8 | name: Yangshun Tay
9 | title: Front End Engineer @ Facebook
10 | url: https://github.com/yangshun
11 | image_url: https://github.com/yangshun.png
12 |
13 | slorber:
14 | name: Sébastien Lorber
15 | title: Docusaurus maintainer
16 | url: https://sebastienlorber.com
17 | image_url: https://github.com/slorber.png
18 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Identifiers/IdentifierRoutes.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Route, Routes } from 'react-router-dom';
3 | import NewPrimaryKeyPage from './pages/NewPrimaryKeyPage/NewPrimaryKeyPage';
4 | import UserIdentifiersList from './pages/UserIdentifiersList/UserIdentifiersList';
5 |
6 | export default function IdentifierRoutes() {
7 | return (
8 |
9 | } />
10 | } />
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/.github/workflows/integrations-push.yml:
--------------------------------------------------------------------------------
1 | name: Push Integration Images
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v2
11 | - name: Login to Docker Hub
12 | uses: docker/login-action@v2
13 | with:
14 | username: ${{ secrets.DOCKERHUB_USERNAME }}
15 | password: ${{ secrets.DOCKERHUB_TOKEN }}
16 | - name: Build
17 | run: make build-integrations
18 | - name: Push
19 | run: make push-integrations
20 |
--------------------------------------------------------------------------------
/docusaurus/blog/2021-08-01-mdx-blog-post.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | slug: mdx-blog-post
3 | title: MDX Blog Post
4 | authors: [slorber]
5 | tags: [docusaurus]
6 | ---
7 |
8 | Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
9 |
10 | :::tip
11 |
12 | Use the power of React to create interactive blog posts.
13 |
14 | ```js
15 |
16 | ```
17 |
18 |
19 |
20 | :::
21 |
--------------------------------------------------------------------------------
/monoid-api/workflow/activity/requestactivity/find_request.go:
--------------------------------------------------------------------------------
1 | package requestactivity
2 |
3 | import "github.com/monoid-privacy/monoid/model"
4 |
5 | type FindRequestArgs struct {
6 | WorkspaceID string `json:"workspaceId"`
7 | }
8 |
9 | func (a *RequestActivity) FindDBSilos(args FindRequestArgs) ([]model.SiloDefinition, error) {
10 | defs := []model.SiloDefinition{}
11 |
12 | if err := a.Conf.DB.Where(
13 | "workspace_id = ?",
14 | args.WorkspaceID,
15 | ).Find(&defs).Error; err != nil {
16 | return nil, err
17 | }
18 |
19 | return defs, nil
20 | }
21 |
--------------------------------------------------------------------------------
/monoid-api/specimport/types.go:
--------------------------------------------------------------------------------
1 | package specimport
2 |
3 | type IntegrationManifestEntry struct {
4 | ID string `yaml:"id"`
5 | Name string `yaml:"name"`
6 | DocURL string `yaml:"documentationUrl"`
7 | DockerImage string `yaml:"dockerImage"`
8 | DockerTag string `yaml:"dockerTag"`
9 | Logo string `yaml:"logo"`
10 | Manual bool `yaml:"manual"`
11 | }
12 |
13 | type IntegrationFullSpecEntry struct {
14 | IntegrationManifestEntry `yaml:",inline"`
15 | Spec map[string]interface{} `yaml:"spec,omitempty"`
16 | }
17 |
--------------------------------------------------------------------------------
/monoid-integrations/Makefile:
--------------------------------------------------------------------------------
1 | INTEGRATIONS = monoid-bigquery monoid-mysql monoid-postgres monoid-redshift monoid-snowflake monoid-mixpanel
2 |
3 | DOCKER_BUILD_TARGETS = $(foreach fd, $(INTEGRATIONS), $(fd)/docker-build)
4 | DOCKER_PUSH_TARGETS = $(foreach fd, $(INTEGRATIONS), $(fd)/docker-push)
5 |
6 | .PHONY: $(DOCKER_BUILD_TARGETS) $(DOCKER_PUSH_TARGETS)
7 |
8 | $(DOCKER_BUILD_TARGETS):
9 | $(MAKE) -C $(@D) build
10 |
11 | $(DOCKER_PUSH_TARGETS):
12 | $(MAKE) -C $(@D) push
13 |
14 | docker-build: $(DOCKER_BUILD_TARGETS)
15 | docker-push: $(DOCKER_PUSH_TARGETS)
16 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/PageCenter.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | export default function PageCenter(props: { children: React.ReactNode, className?: string }) {
5 | const { children, className } = props;
6 | return (
7 |
8 |
9 | {children}
10 |
11 |
12 | );
13 | }
14 |
15 | PageCenter.defaultProps = {
16 | className: '',
17 | };
18 |
--------------------------------------------------------------------------------
/monoid-api/config-data/data-categories.yaml:
--------------------------------------------------------------------------------
1 | - name: Last Name
2 | id: surname
3 | - name: Phone Number
4 | id: phone
5 | - name: Date of Birth
6 | id: date_of_birth
7 | - name: Postal Code
8 | id: postal_code
9 | - name: Oauth Token
10 | id: oauth_token
11 | - name: User ID
12 | id: user_id
13 | - name: Location
14 | id: location
15 | - name: Email
16 | id: email
17 | - name: IP Address
18 | id: ip
19 | - name: Credit Card
20 | id: credit_card
21 | - name: SSN
22 | id: ssn
23 | - name: Street Address
24 | id: street
25 | - name: MAC Address
26 | id: mac
27 |
--------------------------------------------------------------------------------
/monoid-api/scanner/types.go:
--------------------------------------------------------------------------------
1 | package scanner
2 |
3 | import "github.com/monoid-privacy/monoid/monoidprotocol"
4 |
5 | type RuleMatch struct {
6 | RuleName string
7 | DisplayName string
8 | Confidence string
9 | Identifier string
10 | MatchedData []string
11 | MatchType string
12 | SchemaName string
13 | SchemaGroup *string
14 | LineCount int
15 | }
16 |
17 | type SchemaRecordGroup struct {
18 | Schema monoidprotocol.MonoidSchema
19 | Records []monoidprotocol.MonoidRecord
20 | }
21 |
22 | type ValuePath struct {
23 | Path []string
24 | Type string
25 | }
26 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Silos/pages/SiloIndexPage/SiloIndex.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Button from '../../../../components/Button';
3 | import PageHeader from '../../../../components/PageHeader';
4 | import SiloList from './components/SiloList';
5 |
6 | export default function SiloIndex() {
7 | return (
8 | <>
9 |
13 | New Data Silo
14 |
15 | )}
16 | />
17 |
18 | >
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/monoid-api/filestore/filestore.go:
--------------------------------------------------------------------------------
1 | package filestore
2 |
3 | import (
4 | "context"
5 | "io"
6 | )
7 |
8 | type FileStore interface {
9 | // NewWriter returns an io.Writer for the file handle you can write to
10 | // and the path to access the file. Set fullPath to true if the objectName
11 | // is the full path returned by a previous NewWriter call.
12 | NewWriter(
13 | ctx context.Context,
14 | objectName string,
15 | segmentFile bool,
16 | ) (io.WriteCloser, string, error)
17 |
18 | NewReader(ctx context.Context, objectName string, segmentFile bool) (io.ReadCloser, error)
19 | }
20 |
--------------------------------------------------------------------------------
/.github/workflows/go-lint.yml:
--------------------------------------------------------------------------------
1 | name: Go Lint
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | permissions:
8 | contents: read
9 | pull-requests: read
10 |
11 | jobs:
12 | golangci:
13 | name: lint
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/setup-go@v3
17 | with:
18 | go-version: 1.18
19 | - uses: actions/checkout@v3
20 | - name: golangci-lint
21 | uses: golangci/golangci-lint-action@v3
22 | with:
23 | version: v1.48
24 | working-directory: monoid-api
25 | args: --timeout=5m ./...
26 |
--------------------------------------------------------------------------------
/monoid-api/dataloader/jobs.go:
--------------------------------------------------------------------------------
1 | package dataloader
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/graph-gophers/dataloader"
7 | "github.com/monoid-privacy/monoid/model"
8 | )
9 |
10 | // Job wraps the associated dataloader
11 | func Job(ctx context.Context, id string) (*model.Job, error) {
12 | loaders := For(ctx)
13 | return getData[*model.Job](ctx, id, loaders.JobLoader)
14 | }
15 |
16 | // jobs gets all the jobs in keys by ID
17 | func (c *Reader) jobs(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
18 | return loadData[*model.Job](ctx, c.conf.DB, false, keys)
19 | }
20 |
--------------------------------------------------------------------------------
/monoid-api/.golangci.yml:
--------------------------------------------------------------------------------
1 | linters-settings:
2 | errcheck:
3 | without_tests: true
4 | exclude-functions:
5 | - (github.com/monoid-privacy/monoid/monoidprotocol.MonoidProtocol).Teardown
6 | - (github.com/monoid-privacy/monoid/analytics/ingestor.Ingestor).Identify
7 | - (github.com/monoid-privacy/monoid/analytics/ingestor.Ingestor).Close
8 | - (github.com/monoid-privacy/monoid/analytics/ingestor.Ingestor).Track
9 | issues:
10 | exclude-rules:
11 | # Exclude some linters from running on tests files.
12 | - path: _test\.go
13 | linters:
14 | - errcheck
15 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/redshift_lib/helpers.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Mapping, Optional
2 | import redshift_connector
3 | from monoid_pydev.logger import get_logger
4 |
5 | logger = get_logger("redshift")
6 |
7 |
8 | def get_connection(conf: Mapping[str, Any], db_name: Optional[str] = None) -> redshift_connector.Connection:
9 | if db_name is None:
10 | db_name = conf["database"]
11 |
12 | return redshift_connector.connect(
13 | user=conf["username"],
14 | password=conf["password"],
15 | host=conf["host"],
16 | database=db_name,
17 | )
18 |
--------------------------------------------------------------------------------
/monoid-ui/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(
8 | document.getElementById('root') as HTMLElement,
9 | );
10 |
11 | root.render(
12 | ,
13 | );
14 |
15 | // If you want to start measuring performance in your app, pass a function
16 | // to log results (for example: reportWebVitals(console.log))
17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
18 | reportWebVitals();
19 |
--------------------------------------------------------------------------------
/monoid-api/config-data/resources/images/redshift.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/snowflake_lib/helpers.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Mapping, Optional
2 | import snowflake.connector
3 | from monoid_pydev.logger import get_logger
4 |
5 | logger = get_logger("snowflake")
6 |
7 |
8 | def get_connection(conf: Mapping[str, Any], db_name: Optional[str] = None):
9 | if db_name is None:
10 | db_name = conf["database"]
11 |
12 | return snowflake.connector.connect(
13 | user=conf["username"],
14 | password=conf["password"],
15 | account=conf["account"],
16 | warehouse=conf["warehouse"],
17 | database=db_name,
18 | )
19 |
--------------------------------------------------------------------------------
/monoid-ui/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Monoid",
3 | "name": "Monoid | Open Source Privacy",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Requests/pages/RequestIndexPage/RequestIndex.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Button from '../../../../components/Button';
3 | import PageHeader from '../../../../components/PageHeader';
4 | import RequestList from './components/RequestList';
5 |
6 | export default function RequestIndex() {
7 | return (
8 | <>
9 |
13 | New User Data Request
14 |
15 | )}
16 | />
17 |
18 | >
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/.github/workflows/docker-push.yml:
--------------------------------------------------------------------------------
1 | name: Push Core Docker Images
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | workflow_dispatch:
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v2
14 | - name: Login to Docker Hub
15 | uses: docker/login-action@v2
16 | with:
17 | username: ${{ secrets.DOCKERHUB_USERNAME }}
18 | password: ${{ secrets.DOCKERHUB_TOKEN }}
19 | - name: Build
20 | run: make docker-build docker-build-codescan
21 | - name: Push
22 | run: make docker-push docker-push-codescan
23 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/monoid-api/scanner/basicscanner/types.go:
--------------------------------------------------------------------------------
1 | package basicscanner
2 |
3 | type ScanOpts struct {
4 | Limit int
5 | MatchConfig *MatchConfig
6 | }
7 |
8 | type MatchConfig struct {
9 | RegexRules []regexRule
10 | NameRules []nameRule
11 | MultiNameRules []multiNameRule
12 | TokenRules []tokenRule
13 | MinCount int
14 | }
15 |
16 | type MatchLine struct {
17 | Path string
18 | Line string
19 | }
20 |
21 | type MatchFinder struct {
22 | // dims [# rules][# matches]
23 | MatchedValues [][]MatchLine
24 | TokenValues [][]MatchLine
25 | NameValues [][]MatchLine
26 | Count int
27 | matchConfig *MatchConfig
28 | }
29 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/bigquery_lib/helpers.py:
--------------------------------------------------------------------------------
1 | import json
2 | import google.cloud
3 | from typing import Any, Mapping, Optional
4 | from google.cloud import bigquery
5 | from google.oauth2 import service_account
6 | from monoid_pydev.logger import get_logger
7 |
8 | logger = get_logger("bigquery")
9 |
10 |
11 | def get_connection(conf: Mapping[str, Any], db_name: Optional[str] = None) -> google.cloud.bigquery.client.Client:
12 | info = json.loads(conf["service_account_json"])
13 | credentials = service_account.Credentials.from_service_account_info(info)
14 | client = bigquery.Client(credentials=credentials)
15 | return client
16 |
--------------------------------------------------------------------------------
/docs/monoid-cloud/overview.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | Monoid also maintains a cloud offering in paid plans. This includes additional features that are likely useful for larger companies, including:
4 |
5 | * RoPA generation & audit trails
6 | * ML-based PII scanning
7 | * White-glove support and uptime SLA's
8 | * Team features (e.g. assigning controllers)
9 |
10 | Monoid's cloud offering is out of beta and currently available for free [here](https://app.monoid.co). If you're interested in getting a walkthrough of the platform or would like support, please [contact us](mailto:jagath@monoid.co) or [sign up on our homepage](https://monoid.co) and we'll reach out!
11 |
--------------------------------------------------------------------------------
/docs/connector-catalog/data-silo-guides/mysql.md:
--------------------------------------------------------------------------------
1 | # MySQL
2 |
3 | Connecting to MySQL with Monoid works as it does with most standard tools. To do so, navigate to `Data Silos > New Data Silo` from the left-hand sidebar, and select `MySQL` for the Silo type.
4 |
5 | :::caution
6 | If you're connecting to a local MySQL instance after running Docker compose, you'll need to replace `localhost` with `host.docker.internal`
7 | :::
8 |
9 | 
10 |
11 | Simply enter the connection credentials for the MySQL DB, and Monoid will attempt to create a connection. If it succeeds, you will be taken to the newly created MySQL silo's page.
--------------------------------------------------------------------------------
/.env.dev:
--------------------------------------------------------------------------------
1 | # The docker image version that is being used.
2 | VERSION='latest'
3 |
4 | # The URL that the web app will be accessed at.
5 | # This is used to generate links from the server and
6 | # to create the CORS policy.
7 | WEB_URL='http://localhost:3000'
8 |
9 | # The settings for the postgres DB that is used for
10 | # monoid data.
11 | DATABASE_USER='postgres'
12 | DATABASE_PASSWORD='postgres'
13 | DATABASE_NAME='monoid'
14 |
15 | # Analytics key
16 | SEGMENT_KEY='7D1TEdcvJh1l4QVBCfJgyAXx0PZF7vu5'
17 | FILESTORE_PATH='/logs'
18 | LOCAL_FILESTORE_PATH='./monoid-filestore'
19 | LOCAL_TEMPSTORE_PATH='/tmp/monoid'
20 | TEMPORAL_UI_VERSION=2.8.1
21 | RESOURCE_PATH='/resources'
22 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Requests/pages/NewRequestPage/NewRequestPage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useNavigate } from 'react-router-dom';
3 | import Card from '../../../../components/Card';
4 | import PageHeader from '../../../../components/PageHeader';
5 | import NewRequestForm from './components/NewRequestForm';
6 |
7 | export default function NewRequestPage() {
8 | const navigate = useNavigate();
9 |
10 | return (
11 | <>
12 |
13 |
14 | {
15 | navigate(`../${r.id!}`);
16 | }}
17 | />
18 |
19 | >
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/intercom/spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "spec": {
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "type": "object",
5 | "properties": {
6 | "workspace": {
7 | "type": "string",
8 | "title": "Workspace Name",
9 | "order": 1,
10 | "description": "Your Intercom Workspace"
11 | },
12 | "access_token": {
13 | "type": "string",
14 | "secret": true,
15 | "title": "Access Token",
16 | "order": 2,
17 | "description": "Your Intercom Access Token"
18 | }
19 | },
20 | "required": [
21 | "access_token",
22 | "workspace"
23 | ]
24 | }
25 | }
--------------------------------------------------------------------------------
/monoid-ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx",
22 | "baseUrl": "src"
23 | },
24 | "include": [
25 | "src",
26 | "codegen.ts"
27 | ]
28 | }
--------------------------------------------------------------------------------
/monoid-api/dataloader/silo_specifications.go:
--------------------------------------------------------------------------------
1 | package dataloader
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/graph-gophers/dataloader"
7 | "github.com/monoid-privacy/monoid/model"
8 | )
9 |
10 | // SiloSpecification wraps the associated dataloader
11 | func SiloSpecification(ctx context.Context, id string) (*model.SiloSpecification, error) {
12 | loaders := For(ctx)
13 | return getData[*model.SiloSpecification](ctx, id, loaders.SiloSpecificationLoader)
14 | }
15 |
16 | // siloSpecifications gets a list of silo specifications by id
17 | func (c *Reader) siloSpecifications(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
18 | return loadData[*model.SiloSpecification](ctx, c.conf.DB, false, keys)
19 | }
20 |
--------------------------------------------------------------------------------
/monoid-ui/codegen.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import { CodegenConfig } from '@graphql-codegen/cli';
3 |
4 | const config: CodegenConfig = {
5 | schema: '../monoid-api/schema/*.graphqls',
6 | documents: ['src/**/*.tsx', 'src/**/*.ts'],
7 | generates: {
8 | './src/__generated__/': {
9 | preset: 'client',
10 | plugins: [{
11 | add: {
12 | content: '/* eslint-disable */',
13 | },
14 | }],
15 | presetConfig: {
16 | gqlTagName: 'gql',
17 | fragmentMasking: false,
18 | },
19 | config: {
20 | dedupeFragments: true,
21 | },
22 | },
23 | },
24 | ignoreNoDocuments: true,
25 | };
26 |
27 | export default config;
28 |
--------------------------------------------------------------------------------
/monoid-ui/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | # The docker image version that is being used.
2 | VERSION='0.0.1'
3 |
4 | # The URL that the web app will be accessed at.
5 | # This is used to generate links from the server and
6 | # to create the CORS policy.
7 | WEB_URL='http://localhost:8080'
8 |
9 | # The settings for the postgres DB that is used for
10 | # monoid data.
11 | DATABASE_USER='postgres'
12 | DATABASE_PASSWORD='postgres'
13 | DATABASE_NAME='monoid'
14 |
15 | # Analytics key
16 | SEGMENT_KEY='7D1TEdcvJh1l4QVBCfJgyAXx0PZF7vu5'
17 | FILESTORE_PATH='/filestore'
18 | RESOURCE_PATH='/monoid_resources'
19 |
20 | STORAGE_TYPE='local'
21 | GCS_BUCKET=''
22 |
23 | # If using the google_cloud storage type, this should be the path to service account credentials
24 | LOCAL_GOOGLE_CLOUD_JSON=''
25 |
--------------------------------------------------------------------------------
/monoid-api/dataloader/query_results.go:
--------------------------------------------------------------------------------
1 | package dataloader
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/graph-gophers/dataloader"
7 | "github.com/monoid-privacy/monoid/model"
8 | )
9 |
10 | // QueryResult wraps the associated dataloader
11 | func QueryResult(ctx context.Context, id string) (*model.QueryResult, error) {
12 | loaders := For(ctx)
13 | return getData[*model.QueryResult](ctx, id, loaders.QueryResultLoader)
14 | }
15 |
16 | // queryResults gets a list of query results by id
17 | func (c *Reader) queryResults(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
18 | return loadDataField[*model.QueryResult](
19 | ctx,
20 | c.conf.DB,
21 | "request_status_id",
22 | true,
23 | false,
24 | keys,
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Select.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | interface SelectProps extends React.HTMLProps {
5 | onChange: React.ChangeEventHandler
6 | }
7 |
8 | export default function Select(props: SelectProps) {
9 | const { className, children, ...selectProps } = props;
10 |
11 | return (
12 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/monoid-codescan/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * The settings file is used to specify which projects to include in your build.
5 | *
6 | * Detailed information about configuring a multi-project build in Gradle can be found
7 | * in the user manual at https://docs.gradle.org/7.6/userguide/multi_project_builds.html
8 | */
9 |
10 | rootProject.name = "monoid-codescan"
11 | include("app")
12 |
13 | /* includeBuild("../../cpg") { */
14 | /* dependencySubstitution { */
15 | /* substitute(module("com.github.monoid:cpg:cpg-core")).using(project(":cpg-core")) */
16 | /* substitute(module("com.github.monoid:cpg:cpg-core")).using(project(":cpg-language-go")) */
17 | /* } */
18 | /* } */
19 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/docs/monoid-open-source-quick-start/deploy-monoid.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | sidebar_label: "Deploy Monoid"
4 | ---
5 | # Deploy Monoid
6 |
7 | Deploying Monoid Open-Source locally takes just a couple of steps:
8 |
9 | :::tip
10 |
11 | You'll need to have Docker installed to follow these instructions. If you don't have Docker already, you can get it [here](https://www.docker.com/products/docker-desktop).
12 |
13 | :::
14 |
15 | 1. Generate an encryption key with `openssl rand -base64 32`
16 | 2. Run the following commands:
17 |
18 | ```
19 | git clone https://github.com/monoid-privacy/monoid.git
20 | cd monoid
21 | ENCRYPTION_KEY=[key generated in the previous step] docker compose up
22 | ```
23 |
24 | 3. Navigate to `localhost:8080` to create your workspace
25 |
--------------------------------------------------------------------------------
/docker-compose.build.yaml:
--------------------------------------------------------------------------------
1 | version: "3.7"
2 | services:
3 | web:
4 | build:
5 | dockerfile: Dockerfile
6 | context: ./monoid-ui
7 | image: monoidco/monoid-web:${VERSION}
8 | api:
9 | build:
10 | dockerfile: cmd/server/Dockerfile
11 | context: ./monoid-api
12 | image: monoidco/monoid-api:${VERSION}
13 | loader:
14 | build:
15 | dockerfile: cmd/tools/loader/Dockerfile
16 | context: ./monoid-api
17 | image: monoidco/monoid-loader:${VERSION}
18 | worker:
19 | build:
20 | dockerfile: cmd/worker/Dockerfile
21 | context: ./monoid-api
22 | image: monoidco/monoid-worker:${VERSION}
23 | proxy:
24 | build:
25 | dockerfile: Dockerfile
26 | context: ./monoid-proxy
27 | image: monoidco/monoid-proxy:${VERSION}
28 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/BorderedRegion.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | export default function BorderedRegion(props: {
5 | children: React.ReactNode,
6 | label: string,
7 | className?: string
8 | }) {
9 | const { children, label, className } = props;
10 | return (
11 |
12 |
15 | {label}
16 |
17 |
18 | {children}
19 |
20 |
21 | );
22 | }
23 |
24 | BorderedRegion.defaultProps = {
25 | className: '',
26 | };
27 |
--------------------------------------------------------------------------------
/monoid-codescan/app/src/main/kotlin/monoid/codescan/Extension.kt:
--------------------------------------------------------------------------------
1 | package monoid.codescan
2 | import de.fraunhofer.aisec.cpg.TranslationConfiguration
3 | import de.fraunhofer.aisec.cpg.passes.*
4 |
5 | fun TranslationConfiguration.Builder.monoidPasses(): TranslationConfiguration.Builder {
6 | this.registerPass(TypeHierarchyResolver())
7 | this.registerPass(JavaExternalTypeHierarchyResolver())
8 | this.registerPass(ImportResolver())
9 | this.registerPass(VariableUsageResolver())
10 | this.registerPass(CallResolver()) // creates CG
11 | this.registerPass(DFGPass())
12 | this.registerPass(FunctionPointerCallResolver())
13 | // this.registerPass(EvaluationOrderGraphPass()) // creates EOG
14 | this.registerPass(TypeResolver())
15 | this.registerPass(FilenameMapper())
16 | return this
17 | }
--------------------------------------------------------------------------------
/monoid-codescan/app/src/main/kotlin/monoid/codescan/config/CodescanConfig.kt:
--------------------------------------------------------------------------------
1 | package monoid.codescan.config
2 |
3 | import monoid.codescan.generated.enums.CodescanRepoType
4 | import com.fasterxml.jackson.module.kotlin.registerKotlinModule
5 | import com.fasterxml.jackson.module.kotlin.readValue
6 | import com.fasterxml.jackson.dataformat.yaml.YAMLMapper
7 | import java.io.File
8 |
9 | data class CodescanConfig(
10 | val repoId: String,
11 | val repoType: CodescanRepoType
12 | )
13 |
14 | fun readConfig(filepath: File): CodescanConfig {
15 | val mapper = YAMLMapper().registerKotlinModule()
16 | return mapper.readValue(filepath)
17 | }
18 |
19 | fun CodescanConfig.persist(filepath: File) {
20 | val mapper = YAMLMapper().registerKotlinModule()
21 | mapper.writeValue(filepath, this)
22 | }
--------------------------------------------------------------------------------
/monoid-ui/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './App.css';
3 |
4 | import { createUploadLink } from 'apollo-upload-client';
5 | import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
6 | import config from 'cache/config';
7 | import MonoidRouter from './pages/router';
8 | import ToastDisplayer from './components/ToastDisplayer';
9 |
10 | const client = new ApolloClient({
11 | cache: new InMemoryCache(config),
12 | // @ts-ignore
13 | link: createUploadLink({
14 | uri: `${process.env.REACT_APP_API_URL || ''}/query`,
15 | }),
16 | });
17 |
18 | function App() {
19 | return (
20 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 |
28 | export default App;
29 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Divider.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from 'utils/utils';
3 |
4 | interface DividerProps extends React.HTMLProps { }
5 |
6 | export default function Divider(props: DividerProps) {
7 | const { children, className, ...rest } = props;
8 | return (
9 |
10 |
13 | {
14 | children
15 | && (
16 |
17 | {children}
18 |
19 | )
20 | }
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/postgres/helpers.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Mapping, Optional
2 | import psycopg
3 | from monoid_pydev.logger import get_logger
4 |
5 | logger = get_logger("postgres")
6 |
7 |
8 | def get_connection(conf: Mapping[str, Any], db_name: Optional[str] = None) -> psycopg.Connection:
9 | if db_name is None:
10 | db_name = conf["database"]
11 |
12 | connection_str = [
13 | f'host={conf["hostname"]}',
14 | f'port={conf["port"]}',
15 | f'dbname={db_name}',
16 | f'user={conf["username"]}',
17 | f'password={conf["password"]}'
18 | ]
19 |
20 | if conf.get("ssl", False):
21 | connection_str.append("sslmode=prefer")
22 | else:
23 | connection_str.append("sslmode=disable")
24 |
25 | return psycopg.connect(" ".join(connection_str))
26 |
--------------------------------------------------------------------------------
/monoid-api/config-data/resources/images/intercom.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/monoid-api/config-data/resources/images/mixpanel.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/SVGText.tsx:
--------------------------------------------------------------------------------
1 | import React, { DetailedHTMLProps, useMemo } from 'react';
2 | import { Buffer } from 'buffer';
3 | import { classNames } from '../utils/utils';
4 |
5 | type ImgProps = DetailedHTMLProps, HTMLImageElement>;
6 | interface SVGTextProps extends ImgProps {
7 | imageText: string
8 | }
9 |
10 | export default function SVGText(props: SVGTextProps) {
11 | const {
12 | imageText, className, alt, ...rest
13 | } = props;
14 | const imageData = useMemo(() => {
15 | const buff = Buffer.from(imageText);
16 | return buff.toString('base64');
17 | }, [imageText]);
18 |
19 | return (
20 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/monoid-api/schema/jobs.graphqls:
--------------------------------------------------------------------------------
1 | scalar Time
2 |
3 | enum JobStatus {
4 | QUEUED
5 | RUNNING
6 | COMPLETED
7 | PARTIAL_FAILED
8 | FAILED
9 | }
10 |
11 | type Job {
12 | id: ID!
13 | jobType: String!
14 | resourceId: ID!
15 | status: JobStatus!
16 |
17 | siloDefinition: SiloDefinition! @goField(forceResolver: true)
18 | logs: [String!]
19 |
20 | createdAt: Time!
21 | updatedAt: Time!
22 | }
23 |
24 | type JobsResult {
25 | jobs: [Job!]!
26 | numJobs: Int!
27 | }
28 |
29 | extend type Workspace {
30 | jobs(
31 | jobType: String!,
32 | resourceId: ID,
33 | status: [JobStatus],
34 | query: String,
35 | limit: Int!,
36 | offset: Int!
37 | ): JobsResult!
38 |
39 | job(id: ID!): Job!
40 | }
41 |
42 | extend type Mutation {
43 | cancelJob(id: ID!): Job
44 | }
45 |
--------------------------------------------------------------------------------
/monoid-api/cmd/server/.air.toml:
--------------------------------------------------------------------------------
1 | root = "."
2 | testdata_dir = "testdata"
3 | tmp_dir = "tmp"
4 |
5 | [build]
6 | args_bin = []
7 | bin = "./tmp/server"
8 | cmd = "go build -o ./tmp/server cmd/server/main.go"
9 | delay = 1000
10 | exclude_dir = ["assets", "tmp", "vendor", "testdata"]
11 | exclude_file = []
12 | exclude_regex = ["_test.go"]
13 | exclude_unchanged = false
14 | follow_symlink = false
15 | full_bin = ""
16 | include_dir = []
17 | include_ext = ["go", "tpl", "tmpl", "html"]
18 | kill_delay = "0s"
19 | log = "build-errors.log"
20 | send_interrupt = false
21 | stop_on_error = true
22 |
23 | [color]
24 | app = ""
25 | build = "yellow"
26 | main = "magenta"
27 | runner = "green"
28 | watcher = "cyan"
29 |
30 | [log]
31 | time = false
32 |
33 | [misc]
34 | clean_on_exit = false
35 |
36 | [screen]
37 | clear_on_rebuild = false
38 |
--------------------------------------------------------------------------------
/monoid-api/cmd/worker/.air.toml:
--------------------------------------------------------------------------------
1 | root = "."
2 | testdata_dir = "testdata"
3 | tmp_dir = "tmp"
4 |
5 | [build]
6 | args_bin = []
7 | bin = "./tmp/worker"
8 | cmd = "go build -o ./tmp/worker cmd/worker/main.go"
9 | delay = 1000
10 | exclude_dir = ["assets", "tmp", "vendor", "testdata"]
11 | exclude_file = []
12 | exclude_regex = ["_test.go"]
13 | exclude_unchanged = false
14 | follow_symlink = false
15 | full_bin = ""
16 | include_dir = []
17 | include_ext = ["go", "tpl", "tmpl", "html"]
18 | kill_delay = "0s"
19 | log = "build-errors.log"
20 | send_interrupt = false
21 | stop_on_error = true
22 |
23 | [color]
24 | app = ""
25 | build = "yellow"
26 | main = "magenta"
27 | runner = "green"
28 | watcher = "cyan"
29 |
30 | [log]
31 | time = false
32 |
33 | [misc]
34 | clean_on_exit = false
35 |
36 | [screen]
37 | clear_on_rebuild = false
38 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Requests/RequestRoutes.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Navigate, Route, Routes } from 'react-router-dom';
3 | import RequestIndex from './pages/RequestIndexPage/RequestIndex';
4 | import RequestPage from './pages/RequestPage/RequestPage';
5 | import NewRequestPage from './pages/NewRequestPage/NewRequestPage';
6 |
7 | export default function RequestRoutes() {
8 | return (
9 |
10 | } />
11 | } />
12 |
13 | } />
14 | } />
15 | } />
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/monoid-ui/src/graphql/requests_queries.ts:
--------------------------------------------------------------------------------
1 | import { gql } from '__generated__/gql';
2 |
3 | export const GET_PRIMARY_KEYS = gql(`
4 | query GetPrimaryKeys($id: ID!) {
5 | workspace(id: $id) {
6 | id
7 | userPrimaryKeys {
8 | id
9 | name
10 | apiIdentifier
11 | }
12 | }
13 | }
14 | `);
15 |
16 | export const GET_REQUESTS = gql(`
17 | query GetRequests($id: ID!, $limit: Int!, $offset: Int) {
18 | workspace(id: $id) {
19 | id
20 | requests(limit: $limit, offset: $offset) {
21 | requests {
22 | id
23 | type
24 | createdAt
25 | status
26 | }
27 | numRequests
28 | }
29 | }
30 | }
31 | `);
32 |
33 | export const EXECUTE_REQUEST = gql(`
34 | mutation ExecuteRequest($id: ID!) {
35 | executeUserDataRequest(requestId: $id) {
36 | id
37 | status
38 | }
39 | }
40 | `);
41 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/config.ts:
--------------------------------------------------------------------------------
1 | import dataMapCache from './dataMap';
2 | import discoveriesCache from './discoveries';
3 | import jobsQueryCache from './jobs';
4 | import requestsCache from './requests';
5 | import requestStatusCache from './requestStatus';
6 |
7 | export default {
8 | typePolicies: {
9 | Request: {
10 | fields: {
11 | requestStatuses: requestStatusCache(),
12 | },
13 | },
14 | SiloDefinition: {
15 | fields: {
16 | discoveries: discoveriesCache(),
17 | },
18 | },
19 | DataMapRow: {
20 | keyFields: ['siloDefinition', ['id'], 'property', ['id'], 'dataSource', ['id']],
21 | },
22 | Workspace: {
23 | fields: {
24 | jobs: jobsQueryCache(),
25 | discoveries: discoveriesCache(),
26 | requests: requestsCache(),
27 | dataMap: dataMapCache(),
28 | },
29 | },
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/docs/connector-catalog/data-silo-guides/postgres.md:
--------------------------------------------------------------------------------
1 | # Postgres
2 |
3 | Connecting to Postgres with Monoid works as it does with most standard tools. To do so, navigate to `Data Silos > New Data Silo` from the left-hand sidebar, and select `Postgres` for the Silo type.
4 |
5 | :::caution
6 | If you're connecting to a local Postgres instance after running Docker compose, you'll need to replace `localhost` with `host.docker.internal`
7 | :::
8 |
9 | 
10 |
11 | Enter the connection credentials for the Postgres DB. Monoid enables SSL connection as well; indicate whether this is necessary in the relevant part of the form.
12 |
13 | By default, Monoid will connect to every DB. There are two ways to avoid this; you can either indicate DB's to exclude in the `Exclude DBs` section, or you can turn off `Scan All DBs` to connect only to the DB specified in `Default Database`.
--------------------------------------------------------------------------------
/docusaurus/blog/2021-08-26-welcome/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | slug: welcome
3 | title: Welcome
4 | authors: [slorber, yangshun]
5 | tags: [facebook, hello, docusaurus]
6 | ---
7 |
8 | [Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
9 |
10 | Simply add Markdown files (or folders) to the `blog` directory.
11 |
12 | Regular blog authors can be added to `authors.yml`.
13 |
14 | The blog post date can be extracted from filenames, such as:
15 |
16 | - `2019-05-30-welcome.md`
17 | - `2019-05-30-welcome/index.md`
18 |
19 | A blog post folder can be convenient to co-locate blog post images:
20 |
21 | 
22 |
23 | The blog supports tags as well!
24 |
25 | **And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.
26 |
--------------------------------------------------------------------------------
/monoid-api/requests/types.go:
--------------------------------------------------------------------------------
1 | package requests
2 |
3 | import (
4 | "github.com/monoid-privacy/monoid/model"
5 | "github.com/monoid-privacy/monoid/monoidprotocol"
6 | )
7 |
8 | const (
9 | Delete = "delete"
10 | Query = "query"
11 | )
12 |
13 | type RequestHandler interface {
14 | HandleDeletion(request DeletionRequest) ([]monoidprotocol.MonoidRecord, error)
15 | }
16 |
17 | type MonoidRequestHandler struct {
18 | SuccessfulSources []model.DataSource
19 | UnsuccessfulSources []model.DataSource
20 | Records []monoidprotocol.MonoidRecord
21 | }
22 |
23 | // Map from primary key ID to the value for the user
24 | type PrimaryKeyMap map[string]string
25 |
26 | type DeletionRequest struct {
27 | PrimaryKeyMap PrimaryKeyMap
28 | SiloDefinitions []model.SiloDefinition
29 | }
30 |
31 | type QueryRequest struct {
32 | PrimaryKeyMap PrimaryKeyMap
33 | SiloDefinitions []model.SiloDefinition
34 | }
35 |
--------------------------------------------------------------------------------
/monoid-py/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | black==22.10.0
5 | certifi==2022.9.24
6 | chardet==4.0.0
7 | charset-normalizer==2.1.1
8 | click==8.1.3
9 | datamodel-code-generator==0.13.3
10 | dnspython==2.2.1
11 | email-validator==1.3.0
12 | genson==1.2.2
13 | idna==3.4
14 | inflect==5.6.2
15 | isodate==0.6.1
16 | isort==5.10.1
17 | Jinja2==3.1.2
18 | jsonschema==3.2.0
19 | MarkupSafe==2.1.1
20 | mypy-extensions==0.4.3
21 | openapi-schema-validator==0.1.6
22 | openapi-spec-validator==0.3.3
23 | pathspec==0.10.1
24 | platformdirs==2.5.2
25 | prance==0.21.8.0
26 | pycodestyle==2.9.1
27 | pydantic==1.10.2
28 | pyrsistent==0.16.1
29 | PySnooper==1.1.1
30 | PyYAML==6.0
31 | requests==2.28.1
32 | ruamel.yaml==0.17.21
33 | ruamel.yaml.clib==0.2.7
34 | semver==2.13.0
35 | six==1.16.0
36 | toml==0.10.2
37 | tomli==2.0.1
38 | typed-ast==1.5.4
39 | typing_extensions==4.4.0
40 | urllib3==1.26.12
41 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Onboarding/WorkspaceAutoSelect.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useQuery } from '@apollo/client';
3 | import { Navigate } from 'react-router-dom';
4 | import { gql } from '__generated__/gql';
5 | import LoadingPage from '../../common/LoadingPage';
6 | import OnboardingForm from './OnboardingForm';
7 |
8 | const GET_WORKSPACES = gql(`
9 | query GetWorkspaces {
10 | workspaces {
11 | id
12 | }
13 | }
14 | `);
15 |
16 | export default function WorkspaceAutoSelect() {
17 | const { data, loading, error } = useQuery(GET_WORKSPACES);
18 |
19 | if (loading) {
20 | return ;
21 | }
22 |
23 | if (data) {
24 | if (data.workspaces.length === 0) {
25 | return ;
26 | }
27 | }
28 |
29 | if (error) {
30 | return {error.message}
;
31 | }
32 |
33 | return ;
34 | }
35 |
--------------------------------------------------------------------------------
/monoid-api/model/jobs.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | const (
9 | JobTypeDiscoverSources = "discover_sources"
10 | JobTypeExecuteRequest = "execute_request"
11 | )
12 |
13 | type Job struct {
14 | ID string `json:"id"`
15 | WorkspaceID string `json:"workspaceId"`
16 | Workspace Workspace `json:"workspace"`
17 | JobType string `json:"jobType"`
18 | ResourceID string `json:"resourceId"`
19 | LogObject string `json:"logObject"`
20 | Status JobStatus `json:"status"`
21 | TemporalWorkflowID string `json:"temporalWorkflowId"`
22 |
23 | CreatedAt time.Time `json:"createdAt"`
24 | UpdatedAt time.Time `json:"updatedAt"`
25 | }
26 |
27 | func (j *Job) KeyField(field string) (string, error) {
28 | if field == "id" {
29 | return j.ID, nil
30 | }
31 |
32 | return "", fmt.Errorf("unknown field")
33 | }
34 |
--------------------------------------------------------------------------------
/docusaurus/sidebars.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creating a sidebar enables you to:
3 | - create an ordered group of docs
4 | - render a sidebar for each doc of that group
5 | - provide next/previous navigation
6 |
7 | The sidebars can be generated from the filesystem, or explicitly defined here.
8 |
9 | Create as many sidebars as you want.
10 | */
11 |
12 | // @ts-check
13 |
14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
15 | const sidebars = {
16 | // By default, Docusaurus generates a sidebar from the docs folder structure
17 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
18 |
19 | // But you can create a sidebar manually
20 | /*
21 | tutorialSidebar: [
22 | 'intro',
23 | 'hello',
24 | {
25 | type: 'category',
26 | label: 'Tutorial',
27 | items: ['tutorial-basics/create-a-document'],
28 | },
29 | ],
30 | */
31 | };
32 |
33 | module.exports = sidebars;
34 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Headers.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | interface HeaderProps extends React.HTMLProps { }
5 |
6 | export function H1(props: HeaderProps) {
7 | const { children, className, ...rest } = props;
8 | return (
9 |
16 | {children}
17 |
18 | );
19 | }
20 |
21 | export function H2(props: HeaderProps) {
22 | const { children, className, ...rest } = props;
23 | return (
24 |
31 | {children}
32 |
33 | );
34 | }
35 |
36 | export default {
37 | H1,
38 | };
39 |
--------------------------------------------------------------------------------
/monoid-api/workflow/validate_ds.go:
--------------------------------------------------------------------------------
1 | package workflow
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/monoid-privacy/monoid/monoidprotocol"
7 | "github.com/monoid-privacy/monoid/workflow/activity"
8 | "go.temporal.io/sdk/temporal"
9 | "go.temporal.io/sdk/workflow"
10 | )
11 |
12 | type ValidateDSArgs struct {
13 | SiloSpecID string
14 | Config []byte
15 | }
16 |
17 | func (w *Workflow) ValidateDSWorkflow(ctx workflow.Context, args ValidateDSArgs) (monoidprotocol.MonoidValidateMessage, error) {
18 | options := workflow.ActivityOptions{
19 | StartToCloseTimeout: time.Minute * 2,
20 | RetryPolicy: &temporal.RetryPolicy{
21 | MaximumAttempts: 1,
22 | },
23 | }
24 |
25 | ctx = workflow.WithActivityOptions(ctx, options)
26 | res := monoidprotocol.MonoidValidateMessage{}
27 |
28 | ac := activity.Activity{}
29 | err := workflow.ExecuteActivity(ctx, ac.ValidateDataSiloDef, args).Get(ctx, &res)
30 |
31 | return res, err
32 | }
33 |
--------------------------------------------------------------------------------
/docs/monoid-open-source-quick-start/create-user-identifiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2.6
3 | ---
4 |
5 | # Create User Identifiers
6 |
7 | To automate user data requests, Monoid maintains a single source-of-truth for user identifier types that you can map across each of your silos. Whenever a user data request is submitted, you'll indicate the values for all relevant user identifier types, and Monoid will use those values to find the user in each silo.
8 |
9 | To create and manage user identifiers, navigate to `Configuration > Identifiers` on the left sidebar, and click `New Identifier` on the top left corner.
10 |
11 | In the opened form, give your identifier a name (e.g. `Email`) and an ID (e.g. `email`). The ID will be used to programmatically generate user data requests via the Monoid API (so if you were deleting users by email, you'd include `email: ...` in the request).
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/monoid-api/config-data/resources/images/bigquery.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docusaurus/README.md:
--------------------------------------------------------------------------------
1 | # Website
2 |
3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
4 |
5 | ### Installation
6 |
7 | ```
8 | $ yarn
9 | ```
10 |
11 | ### Local Development
12 |
13 | ```
14 | $ yarn start
15 | ```
16 |
17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18 |
19 | ### Build
20 |
21 | ```
22 | $ yarn build
23 | ```
24 |
25 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
26 |
27 | ### Deployment
28 |
29 | Using SSH:
30 |
31 | ```
32 | $ USE_SSH=true yarn deploy
33 | ```
34 |
35 | Not using SSH:
36 |
37 | ```
38 | $ GIT_USER= yarn deploy
39 | ```
40 |
41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
42 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Empty.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 | import { H2 } from './Headers';
4 |
5 | type EmptyStateProps = {
6 | icon: (props: any) => React.ReactElement,
7 | title: string
8 | subtitle: string
9 | action: React.ReactNode,
10 | className?: string
11 | };
12 | export default function EmptyState(props: EmptyStateProps) {
13 | const {
14 | icon, title, subtitle, action, className,
15 | } = props;
16 |
17 | const Icon = icon;
18 |
19 | return (
20 |
21 |
22 |
{title}
23 |
{subtitle}
24 | {action && (
25 |
26 | {action}
27 |
28 | )}
29 |
30 | );
31 | }
32 |
33 | EmptyState.defaultProps = {
34 | className: '',
35 | };
36 |
--------------------------------------------------------------------------------
/monoid-api/cmd/analytics/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 | "os"
6 |
7 | "github.com/gorilla/mux"
8 | "github.com/monoid-privacy/monoid/analytics"
9 | "github.com/monoid-privacy/monoid/analytics/ingestor"
10 | "github.com/rs/zerolog/log"
11 | )
12 |
13 | const defaultPort = "8081"
14 |
15 | func main() {
16 | port := os.Getenv("PORT")
17 | if port == "" {
18 | port = defaultPort
19 | }
20 |
21 | router := mux.NewRouter()
22 |
23 | analyticsHandler := analytics.AnalyticsHandler{
24 | Ingestor: ingestor.NewSegmentIngestor(os.Getenv("SEGMENT_WRITE_KEY"), nil),
25 | }
26 |
27 | defer analyticsHandler.Ingestor.Close()
28 |
29 | router.HandleFunc("/track", analyticsHandler.HandleTrack)
30 | router.HandleFunc("/identify", analyticsHandler.HandleIdentify)
31 |
32 | log.Info().Msgf("starting analytics service on %s", port)
33 | if err := http.ListenAndServe(":"+port, router); err != nil {
34 | log.Err(err).Msg("Error serving")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/monoid-ui/src/graphql/silo_queries.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/prefer-default-export */
2 | import { gql } from '__generated__/gql';
3 |
4 | export const SILO_DATA_SOURCES = gql(`
5 | query SiloDataSources($id: ID!) {
6 | siloDefinition(id: $id) {
7 | id
8 | siloSpecification {
9 | id
10 | manual
11 | }
12 | dataSources {
13 | id
14 | name
15 | group
16 | properties {
17 | id
18 | name
19 | categories {
20 | id
21 | name
22 | }
23 | userPrimaryKey {
24 | id
25 | name
26 | }
27 | }
28 | }
29 | }
30 | }
31 | `);
32 |
33 | export const GET_SILOS = gql(`
34 | query GetSilos($id: ID!) {
35 | workspace(id: $id) {
36 | id
37 | siloDefinitions {
38 | id
39 | name
40 | siloSpecification {
41 | id
42 | name
43 | logo
44 | }
45 | }
46 | }
47 | }
48 | `);
49 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | TEST_SUBDIRS = monoid-api
2 | BUILD_SUBDIRS = monoid-api
3 | INTEGRATIONS_DIR = monoid-integrations
4 | CODESCAN_VERSION = 0.0.1
5 |
6 | TEST_TARGETS = $(foreach fd, $(TEST_SUBDIRS), $(fd)/test)
7 | BUILD_TARGETS = $(foreach fd, $(BUILD_SUBDIRS), $(fd)/build)
8 |
9 | .PHONY: $(TEST_TARGETS)
10 |
11 | $(TEST_TARGETS):
12 | $(MAKE) -C $(@D) test
13 |
14 | $(BUILD_TARGETS):
15 | $(MAKE) -C $(@D) build
16 |
17 | test: $(TEST_TARGETS)
18 | build: $(BUILD_TARGETS)
19 |
20 | docker-build-codescan:
21 | cd monoid-codescan && docker build -t monoidco/monoid-codescan:${CODESCAN_VERSION} .
22 |
23 | docker-push-codescan:
24 | docker push monoidco/monoid-codescan:${CODESCAN_VERSION}
25 |
26 | docker-build:
27 | docker compose -f docker-compose.build.yaml build
28 |
29 | docker-push:
30 | docker compose -f docker-compose.build.yaml push
31 |
32 | build-integrations:
33 | $(MAKE) -C $(INTEGRATIONS_DIR) docker-build
34 |
35 | push-integrations:
36 | $(MAKE) -C $(INTEGRATIONS_DIR) docker-push
37 |
--------------------------------------------------------------------------------
/monoid-api/model/workspace.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import (
4 | "regexp"
5 |
6 | "gorm.io/datatypes"
7 | )
8 |
9 | var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
10 |
11 | type Workspace struct {
12 | ID string
13 | Name string
14 | OnboardingComplete bool `default:"false"`
15 | SiloSpecifications []SiloSpecification
16 | SiloDefinitions []SiloDefinition
17 | Purposes []Purpose
18 | Categories []Category
19 | Requests []Request
20 | UserPrimaryKey []UserPrimaryKey
21 | Settings datatypes.JSON
22 | }
23 |
24 | type WorkspaceSettings struct {
25 | Email string `json:"email"`
26 | SendNews bool `json:"sendNews"`
27 | AnonymizeData bool `json:"anonymizeData"`
28 | }
29 |
30 | func ValidateEmail(email string) bool {
31 | return len(email) > 0 && emailRegex.MatchString(email)
32 | }
33 |
--------------------------------------------------------------------------------
/monoid-api/specimport/tools.go:
--------------------------------------------------------------------------------
1 | package specimport
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/docker/docker/client"
7 | "github.com/monoid-privacy/monoid/monoidprotocol/docker"
8 | )
9 |
10 | // GetFullSpec enriches the manifest entry with the data from the docker image
11 | func GetFullSpec(entry *IntegrationManifestEntry, dockerCli *client.Client) (*IntegrationFullSpecEntry, error) {
12 | ctx := context.Background()
13 |
14 | if entry.Manual {
15 | return &IntegrationFullSpecEntry{
16 | IntegrationManifestEntry: *entry,
17 | }, nil
18 | }
19 |
20 | mp := docker.NewDockerMPWithClient(entry.DockerImage, entry.DockerTag, "", dockerCli, false)
21 | defer mp.Teardown(ctx)
22 |
23 | err := mp.InitConn(ctx)
24 | if err != nil {
25 | return nil, err
26 | }
27 |
28 | spec, err := mp.Spec(ctx)
29 |
30 | if err != nil {
31 | return nil, err
32 | }
33 |
34 | return &IntegrationFullSpecEntry{
35 | IntegrationManifestEntry: *entry,
36 | Spec: spec.Spec,
37 | }, nil
38 | }
39 |
--------------------------------------------------------------------------------
/monoid-api/dataloader/data_sources.go:
--------------------------------------------------------------------------------
1 | package dataloader
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/graph-gophers/dataloader"
7 | "github.com/monoid-privacy/monoid/model"
8 | )
9 |
10 | // DataSource wraps the associated dataloader
11 | func DataSource(ctx context.Context, id string) (*model.DataSource, error) {
12 | loaders := For(ctx)
13 | return getData[*model.DataSource](ctx, id, loaders.DataSourceLoader)
14 | }
15 |
16 | func DataSourceUnscoped(ctx context.Context, id string) (*model.DataSource, error) {
17 | loaders := For(ctx)
18 | return getData[*model.DataSource](ctx, id, loaders.DataSourceLoader)
19 | }
20 |
21 | // dataSources gets all the datasources in keys.
22 | func (c *Reader) dataSources(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
23 | unscoped, ok := ctx.Value(UnscopedKey).(bool)
24 | if ok && unscoped {
25 | return loadDataUnscoped[*model.DataSource](ctx, c.conf.DB, false, keys)
26 | }
27 |
28 | return loadData[*model.DataSource](ctx, c.conf.DB, false, keys)
29 | }
30 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Link.tsx:
--------------------------------------------------------------------------------
1 | import React, { HTMLProps } from 'react';
2 | import { Link, LinkProps } from 'react-router-dom';
3 | import { classNames } from '../utils/utils';
4 |
5 | export function BristLink(props: LinkProps) {
6 | const { className, children } = props;
7 |
8 | return (
9 |
19 | {children}
20 |
21 | );
22 | }
23 |
24 | export function BristA(props: HTMLProps) {
25 | const { className, children } = props;
26 |
27 | return (
28 |
37 | {children}
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/MonoidLink.tsx:
--------------------------------------------------------------------------------
1 | import React, { HTMLProps } from 'react';
2 | import { Link, LinkProps } from 'react-router-dom';
3 | import { classNames } from '../utils/utils';
4 |
5 | export function MonoidLink(props: LinkProps) {
6 | const { className, children } = props;
7 |
8 | return (
9 |
19 | {children}
20 |
21 | );
22 | }
23 |
24 | export function MonoidA(props: HTMLProps) {
25 | const { className, children } = props;
26 |
27 | return (
28 |
37 | {children}
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/monoid-ui/src/hooks/useQueryPatched.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | DocumentNode, OperationVariables, QueryHookOptions, QueryResult, TypedDocumentNode,
3 | useQuery as apolloUseQuery,
4 | } from '@apollo/client';
5 | import { useMemo, useRef } from 'react';
6 |
7 | // useQueryPatched removes fetchPolicy from options after the first
8 | // useQuery call, since it will otherwise not use the nextFetchPolicy.
9 | export default function useQueryPatched(
10 | query: DocumentNode | TypedDocumentNode,
11 | rawOptions?: QueryHookOptions,
12 | ): QueryResult {
13 | const firstUpdate = useRef(true);
14 |
15 | const options = useMemo(() => {
16 | if (firstUpdate.current) {
17 | firstUpdate.current = false;
18 | return rawOptions;
19 | }
20 |
21 | const newOptions = { ...rawOptions };
22 | delete newOptions.fetchPolicy;
23 |
24 | return newOptions;
25 | }, [rawOptions]);
26 |
27 | return apolloUseQuery(query, options);
28 | }
29 |
--------------------------------------------------------------------------------
/docs/connector-catalog/data-silo-guides/redshift.md:
--------------------------------------------------------------------------------
1 | # Amazon Redshift
2 |
3 | :::tip
4 |
5 | You'll need an active Redshift cluster to connect to Monoid. If you don't have one already, you can create it [here](https://docs.aws.amazon.com/ses/latest/dg/event-publishing-redshift-cluster.html).
6 | :::
7 |
8 |
9 |
10 | :::danger
11 |
12 | You'll need to allow connections outside of your Redshift cluster's VPC (if Monoid isn't deployed in the same VPC) or Monoid will not be able to connect. For instructions on how to do so, see [this guide](https://aws.amazon.com/premiumsupport/knowledge-center/redshift-cluster-private-public/).
13 |
14 | :::
15 |
16 | 
17 |
18 | Connecting to Redshift with Monoid works as it does with most standard tools. To do so, navigate to `Data Silos > New Data Silo` from the left-hand sidebar, and select `Redshift` for the Silo type. Then, fill out the credentials; if correct, Monoid will redirect you to your new silo's page to begin a scan for data sources.
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-snowflake/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev
22 | mypy-extensions==0.4.3
23 | openapi-schema-validator==0.1.6
24 | openapi-spec-validator==0.3.3
25 | pathspec==0.10.1
26 | platformdirs==2.5.2
27 | prance==0.21.8.0
28 | psycopg==3.1.4
29 | psycopg-binary==3.1.4
30 | pycodestyle==2.9.1
31 | pydantic==1.10.2
32 | pypika==0.48.9
33 | pyrsistent==0.16.1
34 | PySnooper==1.1.1
35 | PyYAML==6.0
36 | requests==2.28.1
37 | ruamel.yaml==0.17.21
38 | ruamel.yaml.clib==0.2.7
39 | semver==2.13.0
40 | six==1.16.0
41 | toml==0.10.2
42 | tomli==2.0.1
43 | typed-ast==1.5.4
44 | typing_extensions==4.4.0
45 | urllib3==1.26.12
46 |
--------------------------------------------------------------------------------
/docs/monoid-open-source-quick-start/connect-data-silos.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2
3 | ---
4 |
5 | # Connect Data Silos
6 |
7 | Monoid's request automations and scanning are built on top of its collection of [open-source pre-built connectors](/category/connector-catalog).
8 |
9 | ## Add a new Silo
10 |
11 | 1. Navigate to the `Configuration > Data Silos` tab on the left bar.
12 | 2. Click on the `New Data
13 | Silo` button on the top-right corner of the screen.
14 | 3. Choose from one of the available connectors and follow the [corresponding setup guide](/category/data-silo-connector-guides). Can't find a connector you need? You can [create it yourself](/category/build-a-connector), submit an issue on GitHub, or sign up for one of our paid plans to get unlimited on-demand custom connectors.
15 |
16 | 
17 |
18 | :::note
19 | The silo creation flow will look different for each type of silo (Postgres is shown above). For silo-specific guides, see the [Connector Catalog](/category/connector-catalog).
20 |
21 | :::
22 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev==0.0.1a2
22 | mypy-extensions==0.4.3
23 | openapi-schema-validator==0.1.6
24 | openapi-spec-validator==0.3.3
25 | pathspec==0.10.1
26 | platformdirs==2.5.2
27 | prance==0.21.8.0
28 | psycopg==3.1.4
29 | psycopg-binary==3.1.4
30 | pycodestyle==2.9.1
31 | pydantic==1.10.2
32 | pypika==0.48.9
33 | pyrsistent==0.16.1
34 | PySnooper==1.1.1
35 | PyYAML==6.0
36 | requests==2.28.1
37 | ruamel.yaml==0.17.21
38 | ruamel.yaml.clib==0.2.7
39 | semver==2.13.0
40 | six==1.16.0
41 | toml==0.10.2
42 | tomli==2.0.1
43 | typed-ast==1.5.4
44 | typing_extensions==4.4.0
45 | urllib3==1.26.12
46 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-postgres/requirements.dev.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev==0.0.1a1
22 | mypy-extensions==0.4.3
23 | openapi-schema-validator==0.1.6
24 | openapi-spec-validator==0.3.3
25 | pathspec==0.10.1
26 | platformdirs==2.5.2
27 | prance==0.21.8.0
28 | psycopg==3.1.4
29 | psycopg-binary==3.1.4
30 | pycodestyle==2.9.1
31 | pydantic==1.10.2
32 | pypika==0.48.9
33 | pyrsistent==0.16.1
34 | PySnooper==1.1.1
35 | PyYAML==6.0
36 | requests==2.28.1
37 | ruamel.yaml==0.17.21
38 | ruamel.yaml.clib==0.2.7
39 | semver==2.13.0
40 | six==1.16.0
41 | toml==0.10.2
42 | tomli==2.0.1
43 | typed-ast==1.5.4
44 | typing_extensions==4.4.0
45 | urllib3==1.26.12
46 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Identifiers/pages/NewPrimaryKeyPage/NewPrimaryKeyPage.tsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react';
2 | import { useNavigate } from 'react-router-dom';
3 | import PageHeader from 'components/PageHeader';
4 | import ToastContext from 'contexts/ToastContext';
5 | import { XCircleIcon } from '@heroicons/react/24/outline';
6 | import NewPrimaryKeyForm from './components/NewPrimaryKeyForm';
7 |
8 | export default function NewPrimaryKeyPage() {
9 | const navigate = useNavigate();
10 | const toastCtx = useContext(ToastContext);
11 |
12 | return (
13 | <>
14 |
15 | {
17 | navigate('..');
18 | }}
19 | onError={(err) => {
20 | toastCtx.showToast(
21 | {
22 | title: 'Error Creating Identifier',
23 | message: err.message,
24 | variant: 'danger',
25 | icon: XCircleIcon,
26 | },
27 | );
28 | }}
29 | />
30 | >
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/ToastDisplayer.tsx:
--------------------------------------------------------------------------------
1 | import React, { useMemo, useState } from 'react';
2 | import { v4 as uuidv4 } from 'uuid';
3 | import ToastContext from '../contexts/ToastContext';
4 | import Toast, { ToastData } from './Toast';
5 |
6 | export default function ToastDisplayer(props: { children: React.ReactNode }) {
7 | const [toastList, setToastList] = useState([]);
8 | const { children } = props;
9 |
10 | const toastCtxVal = useMemo(() => ({
11 | showToast: (message: {
12 | title: string,
13 | message: React.ReactNode,
14 | variant?: 'success' | 'danger',
15 | icon: (props: any) => React.ReactElement
16 | }) => {
17 | setToastList([
18 | ...toastList,
19 | {
20 | ...message,
21 | id: uuidv4(),
22 | },
23 | ]);
24 | },
25 | }), []);
26 |
27 | return (
28 |
31 | {children}
32 |
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mysql/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev
22 | mypy-extensions==0.4.3
23 | mysql-connector-python==8.0.31
24 | openapi-schema-validator==0.1.6
25 | openapi-spec-validator==0.3.3
26 | pathspec==0.10.1
27 | platformdirs==2.5.2
28 | prance==0.21.8.0
29 | psycopg==3.1.4
30 | psycopg-binary==3.1.4
31 | pycodestyle==2.9.1
32 | pydantic==1.10.2
33 | pypika==0.48.9
34 | pyrsistent==0.16.1
35 | PySnooper==1.1.1
36 | PyYAML==6.0
37 | requests==2.28.1
38 | ruamel.yaml==0.17.21
39 | ruamel.yaml.clib==0.2.7
40 | semver==2.13.0
41 | six==1.16.0
42 | toml==0.10.2
43 | tomli==2.0.1
44 | typed-ast==1.5.4
45 | typing_extensions==4.4.0
46 | urllib3==1.26.12
47 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev
22 | mypy-extensions==0.4.3
23 | openapi-schema-validator==0.1.6
24 | openapi-spec-validator==0.3.3
25 | pathspec==0.10.1
26 | platformdirs==2.5.2
27 | prance==0.21.8.0
28 | psycopg==3.1.4
29 | psycopg-binary==3.1.4
30 | pycodestyle==2.9.1
31 | pydantic==1.10.2
32 | pypika==0.48.9
33 | pyrsistent==0.16.1
34 | PySnooper==1.1.1
35 | PyYAML==6.0
36 | redshift-connector==2.0.909
37 | requests==2.28.1
38 | ruamel.yaml==0.17.21
39 | ruamel.yaml.clib==0.2.7
40 | semver==2.13.0
41 | six==1.16.0
42 | toml==0.10.2
43 | tomli==2.0.1
44 | typed-ast==1.5.4
45 | typing_extensions==4.4.0
46 | urllib3==1.26.12
47 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Silos/pages/NewSiloPage/NewSiloPage.tsx:
--------------------------------------------------------------------------------
1 | import { ExclamationCircleIcon } from '@heroicons/react/24/outline';
2 | import React, { useContext } from 'react';
3 | import { useNavigate } from 'react-router-dom';
4 | import PageHeader from '../../../../components/PageHeader';
5 | import ToastContext from '../../../../contexts/ToastContext';
6 | import NewSiloForm from './components/NewSiloForm';
7 |
8 | export default function NewSiloPage() {
9 | const navigate = useNavigate();
10 | const toastCtx = useContext(ToastContext);
11 |
12 | return (
13 | <>
14 |
15 | {
17 | navigate(`../${sd.id}`);
18 | }}
19 | onError={() => { }}
20 | onCancel={() => {
21 | toastCtx.showToast({
22 | title: 'Cancelled',
23 | message: 'Cancelled successfully.',
24 | icon: ExclamationCircleIcon,
25 | variant: 'success',
26 | });
27 | }}
28 | />
29 | >
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/docs/monoid-open-source-quick-start/create-data-map.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 3
3 | sidebar_label: "Map Data"
4 | ---
5 |
6 | # Map Data
7 |
8 | ## Create the Data Map
9 |
10 | Once you've [connected](connect-data-silos.md) a silo and scanned for data sources, you can annotate the elements of each data source schema.
11 |
12 | To do so, navigate to your data source's page and click on the `Data Sources` tab. Click on a source to open up a drop-down menu with each property of the source's schema. Here, you can assign categories, indicate whether a property is a [user identifier](create-user-identifiers), and select a Purpose of Processing (available in our cloud offering).
13 |
14 | :::tip
15 | To automate user request fulfillment for a data source, you **must** indicate at least one user identifier among the properties of the source.
16 | :::
17 |
18 | ## Manage the Data Map
19 |
20 | Once you've mapped data source properties, you can access views of your data map tab in `Data Map` on the left sidebar. There, you can filter across silos, sources, and properties to find where user data lives.
21 |
--------------------------------------------------------------------------------
/monoid-api/schema/silo_definitions.graphqls:
--------------------------------------------------------------------------------
1 | scalar Map
2 |
3 | input UpdateSiloDefinitionInput {
4 | id: ID!
5 |
6 | name: String
7 | description: String
8 |
9 | siloData: String
10 | }
11 |
12 | type SiloDefinition {
13 | id: ID!
14 | name: String!
15 | description: String
16 | siloSpecification: SiloSpecification @goField(forceResolver: true)
17 | dataSources: [DataSource!] @goField(forceResolver: true)
18 | siloConfig: Map
19 | }
20 |
21 | input CreateSiloDefinitionInput {
22 | description: String
23 | siloSpecificationID: ID!
24 | workspaceID: ID!
25 | siloData: String
26 | name: String!
27 | }
28 |
29 | extend type Query {
30 | siloDefinition(id: ID!): SiloDefinition!
31 | }
32 |
33 | extend type Mutation {
34 | createSiloDefinition(input: CreateSiloDefinitionInput): SiloDefinition!
35 | updateSiloDefinition(input: UpdateSiloDefinitionInput): SiloDefinition!
36 | deleteSiloDefinition(id: ID!): ID!
37 | }
38 |
39 | extend type Workspace {
40 | siloDefinitions: [SiloDefinition!]! @goField(forceResolver: true)
41 | }
42 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mariadb/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev
22 | mypy-extensions==0.4.3
23 | mariadb==1.0.7
24 | openapi-schema-validator==0.1.6
25 | openapi-spec-validator==0.3.3
26 | packaging==20.9
27 | pathspec==0.10.1
28 | platformdirs==2.5.2
29 | prance==0.21.8.0
30 | psycopg==3.1.4
31 | psycopg-binary==3.1.4
32 | pycodestyle==2.9.1
33 | pydantic==1.10.2
34 | pypika==0.48.9
35 | pyrsistent==0.16.1
36 | PySnooper==1.1.1
37 | PyYAML==6.0
38 | requests==2.28.1
39 | ruamel.yaml==0.17.21
40 | ruamel.yaml.clib==0.2.7
41 | semver==2.13.0
42 | six==1.16.0
43 | toml==0.10.2
44 | tomli==2.0.1
45 | typed-ast==1.5.4
46 | typing_extensions==4.4.0
47 | urllib3==1.26.12
48 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-redshift/requirements.dev.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev==0.0.1a1
22 | mypy-extensions==0.4.3
23 | openapi-schema-validator==0.1.6
24 | openapi-spec-validator==0.3.3
25 | pathspec==0.10.1
26 | platformdirs==2.5.2
27 | prance==0.21.8.0
28 | psycopg==3.1.4
29 | psycopg-binary==3.1.4
30 | pycodestyle==2.9.1
31 | pydantic==1.10.2
32 | pypika==0.48.9
33 | pyrsistent==0.16.1
34 | PySnooper==1.1.1
35 | PyYAML==6.0
36 | redshift-connector==2.0.909
37 | requests==2.28.1
38 | ruamel.yaml==0.17.21
39 | ruamel.yaml.clib==0.2.7
40 | semver==2.13.0
41 | six==1.16.0
42 | toml==0.10.2
43 | tomli==2.0.1
44 | typed-ast==1.5.4
45 | typing_extensions==4.4.0
46 | urllib3==1.26.12
47 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev
22 | mypy-extensions==0.4.3
23 | mysql-connector-python==8.0.31
24 | openapi-schema-validator==0.1.6
25 | openapi-spec-validator==0.3.3
26 | pathspec==0.10.1
27 | platformdirs==2.5.2
28 | prance==0.21.8.0
29 | psycopg==3.1.4
30 | psycopg-binary==3.1.4
31 | pycodestyle==2.9.1
32 | pydantic==1.10.2
33 | pypika==0.48.9
34 | pyrsistent==0.16.1
35 | PySnooper==1.1.1
36 | PyYAML==6.0
37 | requests==2.28.1
38 | ruamel.yaml==0.17.21
39 | ruamel.yaml.clib==0.2.7
40 | semver==2.13.0
41 | six==1.16.0
42 | toml==0.10.2
43 | tomli==2.0.1
44 | typed-ast==1.5.4
45 | typing_extensions==4.4.0
46 | urllib3==1.26.12
47 | uuid==1.30
48 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mixpanel/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | idna==3.4
15 | inflect==5.6.2
16 | isodate==0.6.1
17 | isort==5.10.1
18 | Jinja2==3.1.2
19 | jsonschema==3.2.0
20 | MarkupSafe==2.1.1
21 | monoid-pydev
22 | mypy-extensions==0.4.3
23 | mysql-connector-python==8.0.31
24 | openapi-schema-validator==0.1.6
25 | openapi-spec-validator==0.3.3
26 | pathspec==0.10.1
27 | platformdirs==2.5.2
28 | prance==0.21.8.0
29 | psycopg==3.1.4
30 | psycopg-binary==3.1.4
31 | pycodestyle==2.9.1
32 | pydantic==1.10.2
33 | pypika==0.48.9
34 | pyrsistent==0.16.1
35 | PySnooper==1.1.1
36 | PyYAML==6.0
37 | requests==2.28.1
38 | ruamel.yaml==0.17.21
39 | ruamel.yaml.clib==0.2.7
40 | semver==2.13.0
41 | six==1.16.0
42 | toml==0.10.2
43 | tomli==2.0.1
44 | typed-ast==1.5.4
45 | typing_extensions==4.4.0
46 | urllib3==1.26.12
47 | uuid==1.30
48 |
--------------------------------------------------------------------------------
/monoid-ui/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true
5 | },
6 | extends: [
7 | 'plugin:react/recommended',
8 | 'airbnb',
9 | 'airbnb-typescript'
10 | ],
11 | ignorePatterns: [
12 | '.eslintrc.js', 'react-app-env.d.ts', 'build/*',
13 | 'postcss.config.js', 'tailwind.config.js',
14 | ],
15 | parser: '@typescript-eslint/parser',
16 | parserOptions: {
17 | ecmaFeatures: {
18 | jsx: true
19 | },
20 | ecmaVersion: 'latest',
21 | sourceType: 'module',
22 | project: './tsconfig.json'
23 | },
24 | plugins: [
25 | 'react',
26 | '@typescript-eslint'
27 | ],
28 | settings: {
29 | 'import/resolver': {
30 | node: {
31 | extensions: ['.js', '.jsx', '.ts', '.tsx']
32 | }
33 | }
34 | },
35 | rules: {
36 | 'jsx-a11y/label-has-associated-control': 'off',
37 | 'react/jsx-props-no-spreading': [
38 | 2, {
39 | html: 'ignore',
40 | custom: 'enforce',
41 | explicitSpread: 'ignore',
42 | exceptions: []
43 | }
44 | ]
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Silos/pages/SiloPage/components/PropertyCategoryCombobox.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | useMutation,
3 | } from '@apollo/client';
4 | import React from 'react';
5 | import { gql } from '__generated__/gql';
6 | import CategoryCombobox from './CategoryCombobox';
7 |
8 | const UPDATE_CATEGORIES = gql(`
9 | mutation UpdateCategories($input: UpdatePropertyInput!) {
10 | updateProperty(input: $input) {
11 | __typename
12 | id
13 | categories {
14 | id
15 | name
16 | }
17 | }
18 | }
19 | `);
20 |
21 | export default function PropertyCategoryCombobox(props: {
22 | value: string[],
23 | propertyId: string,
24 | }) {
25 | const { value, propertyId } = props;
26 | const [updateCat] = useMutation(UPDATE_CATEGORIES);
27 |
28 | return (
29 | {
32 | updateCat({
33 | variables: {
34 | input: {
35 | id: propertyId,
36 | categoryIDs: v,
37 | },
38 | },
39 | });
40 | }}
41 | />
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/docs/connector-catalog/data-silo-guides/snowflake.md:
--------------------------------------------------------------------------------
1 | # Snowflake
2 |
3 | ## Setup
4 |
5 | To provide Monoid with necessary access, you will need an `ACCOUNTADMIN`-role account with `USAGE` privileges on all relevant databases. If you do not have access to this, please contact your Snowflake administrator to set it up for you.
6 |
7 | Furthermore, you will need to indicate a warehouse for Monoid to use.
8 |
9 | ## Adding the Silo
10 |
11 | 
12 |
13 | Monoid currently supports login authentication for Snowflake. To get your `Account`, go to your Snowflake dashboard, and follow the menus from the bottom left to click on the copy icon shown in the image below; convert your copied account from period-separated to hyphen-separated before pasting (e.g. from `ABCDE.FGHIJ` to `ABCDE-FGHIJ`).
14 |
15 | 
16 |
17 | :::tip
18 | If you run into issues, there may be problems around your permissions. Please feel free to [reach out](mailto:jagath@monoid.co) and we'll help you diagnose what's going wrong.
19 | :::
--------------------------------------------------------------------------------
/monoid-codescan/README.md:
--------------------------------------------------------------------------------
1 | # Monoid Code Scanning
2 |
3 | This folder includes the OSS version of Monoid's code scanning features. A basic
4 | set of config files to use with the scanner can be found in the `config` folder --
5 | it does not have a complete set of scanning criteria by any means -- you'll likely
6 | need to add your own sets of matching criterial.
7 |
8 | ## Configuration
9 |
10 | If you want a pre-configured scanning tool, please [contact us](mailto:support@monoid.co), and
11 | we can get you set up with the beta of our closed-source scanner, which includes a complete set
12 | of configuration files you can use to get started.
13 |
14 | ## Running the Docker Image
15 | To analyze a repository, you can use the `monoidco/monoid-codescan` docker image. The following
16 | command will analyze a repository on your docker host with the example config in `monoid-codescan/config`,
17 | assuming you are in the root of this repository:
18 |
19 | ```
20 | docker run -v $(pwd)/monoid-codescan/config:/config -v /path/to/repo-on-host:/analyze_repo monoidco/monoid-codescan:0.0.1 -c /config /analyze_repo
21 | ```
22 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/requirements.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | google-auth==2.14.1
15 | google-cloud-bigquery==3.4.0
16 | idna==3.4
17 | inflect==5.6.2
18 | isodate==0.6.1
19 | isort==5.10.1
20 | Jinja2==3.1.2
21 | jsonschema==3.2.0
22 | MarkupSafe==2.1.1
23 | monoid-pydev==0.0.1a2
24 | mypy-extensions==0.4.3
25 | openapi-schema-validator==0.1.6
26 | openapi-spec-validator==0.3.3
27 | pathspec==0.10.1
28 | platformdirs==2.5.2
29 | prance==0.21.8.0
30 | psycopg==3.1.4
31 | psycopg-binary==3.1.4
32 | pycodestyle==2.9.1
33 | pydantic==1.10.2
34 | pypika==0.48.9
35 | pyrsistent==0.16.1
36 | PySnooper==1.1.1
37 | PyYAML==6.0
38 | requests==2.28.1
39 | ruamel.yaml==0.17.21
40 | ruamel.yaml.clib==0.2.7
41 | semver==2.13.0
42 | six==1.16.0
43 | toml==0.10.2
44 | tomli==2.0.1
45 | typed-ast==1.5.4
46 | typing_extensions==4.4.0
47 | urllib3==1.26.12
48 |
--------------------------------------------------------------------------------
/monoid-py/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2022 Monoid, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/requirements.dev.txt:
--------------------------------------------------------------------------------
1 | argcomplete==2.0.0
2 | attrs==22.1.0
3 | autopep8==2.0.0
4 | backports.zoneinfo==0.2.1
5 | black==22.10.0
6 | certifi==2022.9.24
7 | chardet==4.0.0
8 | charset-normalizer==2.1.1
9 | click==8.1.3
10 | datamodel-code-generator==0.13.3
11 | dnspython==2.2.1
12 | email-validator==1.3.0
13 | genson==1.2.2
14 | google-auth==2.14.1
15 | google-cloud-bigquery==3.4.0
16 | idna==3.4
17 | inflect==5.6.2
18 | isodate==0.6.1
19 | isort==5.10.1
20 | Jinja2==3.1.2
21 | jsonschema==3.2.0
22 | MarkupSafe==2.1.1
23 | monoid-pydev==0.0.1a1
24 | mypy-extensions==0.4.3
25 | openapi-schema-validator==0.1.6
26 | openapi-spec-validator==0.3.3
27 | pathspec==0.10.1
28 | platformdirs==2.5.2
29 | prance==0.21.8.0
30 | psycopg==3.1.4
31 | psycopg-binary==3.1.4
32 | pycodestyle==2.9.1
33 | pydantic==1.10.2
34 | pypika==0.48.9
35 | pyrsistent==0.16.1
36 | PySnooper==1.1.1
37 | PyYAML==6.0
38 | requests==2.28.1
39 | ruamel.yaml==0.17.21
40 | ruamel.yaml.clib==0.2.7
41 | semver==2.13.0
42 | six==1.16.0
43 | toml==0.10.2
44 | tomli==2.0.1
45 | typed-ast==1.5.4
46 | typing_extensions==4.4.0
47 | urllib3==1.26.12
48 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-bigquery/bigquery_lib/spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "spec": {
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "type": "object",
5 | "properties": {
6 | "service_account_json": {
7 | "type": "string",
8 | "secret": true,
9 | "title": "Service Account JSON",
10 | "description": "The authentication key JSON for the created service account.",
11 | "order": 0
12 | },
13 | "exclude_dbs": {
14 | "title": "Exclude DBs",
15 | "description": "A list of databases to exclude for silo discovery.",
16 | "type": "array",
17 | "items": {
18 | "type": "string"
19 | },
20 | "minItems": 0,
21 | "uniqueItems": true,
22 | "default": [],
23 | "order": 1
24 | },
25 | "scan_all": {
26 | "type": "boolean",
27 | "title": "Scan All DBs",
28 | "description": "If true, Monoid will scan all databases.",
29 | "default": true,
30 | "order": 2
31 | }
32 | },
33 | "required": [
34 | "service_account_json"
35 | ]
36 | }
37 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Monoid, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-intercom/intercom/intercom_silo.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 | from typing import Any, Mapping, List
3 | from monoid_pydev.silos import AbstractSilo
4 | from monoid_pydev.silos.data_store import DataStore
5 | from monoid_pydev.models import MonoidValidateMessage, Status
6 |
7 | from intercom.intercom_store import IntercomDataStore, IntercomContactStore, IntercomConversationStore, IntercomEventStore
8 |
9 | class IntercomSilo(AbstractSilo):
10 | def data_stores(self, conf: Mapping[str, Any]) -> List[DataStore]:
11 | return [IntercomContactStore(
12 | access_token=conf["access_token"],
13 | workspace=conf["workspace"]),
14 | IntercomConversationStore(
15 | access_token=conf["access_token"],
16 | workspace=conf["workspace"]),
17 | IntercomEventStore(
18 | access_token=conf["access_token"],
19 | workspace=conf["workspace"])]
20 |
21 |
22 | def validate(self, conf: Mapping[str, Any]) -> MonoidValidateMessage:
23 | return MonoidValidateMessage(
24 | status=Status.SUCCESS
25 | )
--------------------------------------------------------------------------------
/monoid-api/schema/base.graphqls:
--------------------------------------------------------------------------------
1 | # GraphQL schema example
2 | #
3 | # https://gqlgen.com/getting-started/
4 |
5 | directive @goField(
6 | forceResolver: Boolean
7 | name: String
8 | ) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
9 |
10 | type Workspace {
11 | id: ID!
12 | name: String
13 | onboardingComplete: Boolean
14 | settings: Map! @goField(forceResolver: true)
15 | siloSpecifications: [SiloSpecification!]! @goField(forceResolver: true)
16 | categories: [Category!]! @goField(forceResolver: true)
17 | }
18 |
19 | type Query {
20 | workspaces: [Workspace]!
21 | workspace(id: ID!): Workspace!
22 | }
23 |
24 | input KVPair {
25 | key: String!
26 | value: String!
27 | }
28 |
29 | input CreateWorkspaceInput {
30 | name: String!
31 | settings: [KVPair]
32 | }
33 |
34 | input UpdateWorkspaceSettingsInput {
35 | workspaceID: ID!
36 | settings: [KVPair]
37 | }
38 |
39 | extend type Mutation {
40 | createWorkspace(input: CreateWorkspaceInput!): Workspace!
41 | updateWorkspaceSettings(input: UpdateWorkspaceSettingsInput!): Workspace!
42 | deleteWorkspace(id: ID!): ID!
43 | completeWorkspaceOnboarding(id: ID!): Workspace!
44 | }
45 |
--------------------------------------------------------------------------------
/monoid-ui/src/graphql/jobs_queries.ts:
--------------------------------------------------------------------------------
1 | import { gql } from '__generated__/gql';
2 |
3 | // eslint-disable-next-line import/prefer-default-export
4 | export const GET_ALL_SCANS = gql(`
5 | query GetWorkspaceScans($workspaceId: ID!, $status: [JobStatus], $query: String, $limit: Int!, $offset: Int!) {
6 | workspace(id: $workspaceId) {
7 | id
8 | jobs(
9 | jobType: "discover_sources",
10 | status: $status,
11 | limit: $limit,
12 | offset: $offset,
13 | query: $query
14 | ) {
15 | jobs {
16 | id
17 | jobType
18 | status
19 | createdAt
20 | siloDefinition {
21 | id
22 | name
23 | siloSpecification {
24 | id
25 | name
26 | logo
27 | }
28 | }
29 | }
30 | numJobs
31 | }
32 | }
33 | }
34 | `);
35 |
36 | export const RUN_SOURCE_SCAN = gql(`
37 | mutation RunSourceScan($id: ID!, $workspaceId: ID!) {
38 | detectSiloSources(id: $id, workspaceId: $workspaceId) {
39 | id
40 | status
41 | jobType
42 | }
43 | }
44 | `);
45 |
--------------------------------------------------------------------------------
/connector-testing-ui/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "monoid-connector-testing",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "fs": "^0.0.1-security",
10 | "jsoneditor": "^9.9.2",
11 | "jsoneditor-react": "^3.1.2",
12 | "prismjs": "^1.29.0",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0",
15 | "react-scripts": "5.0.1",
16 | "react-simple-code-editor": "^0.13.1",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/docs/connector-catalog/data-silo-guides/bigquery.md:
--------------------------------------------------------------------------------
1 | # Google BigQuery
2 |
3 | ## Service Account Setup
4 |
5 | Monoid accesses your BigQuery data stores through a dedicated service account. To set up the service account, follow the instructions [here](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating).
6 |
7 | :::caution
8 |
9 | Depending on your access controls and default role, you may need to enable certain permissions for your created service account. Monoid's needs permissions to **read** and **edit** data in BigQuery.
10 |
11 | :::
12 |
13 | Then, create a JSON service account key by following [these instructions]. You'll need to enter the text of the key directly into Monoid; the easiest way to do so is to download the key, then (on MacOS) run the command `pbcopy < [key file].json`
14 |
15 | ## Adding the Silo
16 |
17 | 
18 |
19 | Fill out the fields in the connector form. Enter the service account JSON key (instructions above) in the corresponding field; that is the only required field for BigQuery. By default, Monoid grabs all data stores; to exclude certain data stores, enter their names in the Exclude DBs field.
--------------------------------------------------------------------------------
/docs/project-overview/roadmap.md:
--------------------------------------------------------------------------------
1 | # Monoid Roadmap
2 |
3 | Properly structuring the Monoid roadmap is still a WIP (in fact, it's on the roadmap!). At the moment, this page is just a list of many planned short-term additions to the Monoid platform.
4 |
5 | ## Connectors
6 |
7 | ### Analytics Tools
8 |
9 | * Amplitude (in testing, not yet public)
10 | * Segment (in testing, not yet public)
11 |
12 | ### CRMs
13 |
14 | * Salesforce
15 | * Hubspot
16 | * Outreach.io
17 | * Braze
18 | * Customer.io
19 |
20 | ### Databases
21 |
22 | * MongoDB (in testing, not yet public)
23 | * Firebase (in testing, not yet public)
24 | * SingleStore
25 | * Cassandra
26 |
27 | ### Ads
28 |
29 | * Facebook Ad Manager (in testing, not yet public)
30 | * Snap Ads
31 | * Google Ad Manager (in testing, not yet public)
32 |
33 | ### Other
34 |
35 | * Webhooks
36 | * Optimizely
37 | * Vero
38 | * Appcues
39 | * tray.io
40 | * Iterable
41 |
42 | ## Monoid Platform
43 |
44 | * Cookie banners
45 | * Code scanning
46 |
47 | ## Docs
48 |
49 | * Structure roadmap
50 | * Structure contribution guidelines
51 | * Create code of conduct
52 |
53 |
54 | To add suggestions, please feel free to submit a PR for this file or submit an issue (or both!)
--------------------------------------------------------------------------------
/monoid-ui/src/components/Checkbox.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | interface CheckboxProps extends React.HTMLProps {
5 | checkboxLabel?: React.ReactNode
6 | onChange: React.ChangeEventHandler
7 | }
8 |
9 | function Checkbox(props: CheckboxProps) {
10 | const {
11 | checkboxLabel, className, id, ...cbProps
12 | } = props;
13 |
14 | return (
15 |
16 |
17 |
28 |
29 |
30 |
33 |
34 |
35 | );
36 | }
37 |
38 | Checkbox.defaultProps = {
39 | checkboxLabel: undefined,
40 | };
41 |
42 | export default Checkbox;
43 |
--------------------------------------------------------------------------------
/docs/connector-catalog/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | sidebar_label: "Overview"
4 | ---
5 |
6 | # Overview
7 |
8 | Monoid is built around connectors to data silos that contain user data, including both internal (DB's, warehouses, etc.) external (e.g. SaaS apps) data stores. A full Monoid connector is able to automatically scan, query, and delete from a connected silo to fulfill data deletion/export requests and generate compliance reports.
9 |
10 | The maintainers and the community are regularly adding new prebuilt connectors to the Open-Source repo. If Monoid is missing a connector you'd like, you can build your own easily using our [guide](/category/build-a-connector). Alternatively, you can submit an issue on GitHub and we'll get to it as soon as possible, or sign up for a paid plan to get custom connectors on-demand.
11 |
12 | The following page contains guides for setting up each pre-built connector currently in the repo. While we try our best to keep it up-to-date, it is always a work-in-progress and may be missing guides for connectors contributed by the community -- if you can't find a guide, please submit an issue on GitHub and we'll add it ASAP (or feel free to create a PR to add the guide yourself!).
13 |
--------------------------------------------------------------------------------
/docusaurus/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-website",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "docusaurus": "docusaurus",
7 | "start": "docusaurus start",
8 | "build": "docusaurus build",
9 | "swizzle": "docusaurus swizzle",
10 | "deploy": "docusaurus deploy",
11 | "clear": "docusaurus clear",
12 | "serve": "docusaurus serve",
13 | "write-translations": "docusaurus write-translations",
14 | "write-heading-ids": "docusaurus write-heading-ids"
15 | },
16 | "dependencies": {
17 | "@docusaurus/core": "2.2.0",
18 | "@docusaurus/preset-classic": "2.2.0",
19 | "@mdx-js/react": "^1.6.22",
20 | "clsx": "^1.2.1",
21 | "prism-react-renderer": "^1.3.5",
22 | "react": "^17.0.2",
23 | "react-dom": "^17.0.2"
24 | },
25 | "devDependencies": {
26 | "@docusaurus/module-type-aliases": "2.2.0"
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.5%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | },
40 | "engines": {
41 | "node": ">=16.14"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Silos/pages/SiloPage/components/CategoryBadge.tsx:
--------------------------------------------------------------------------------
1 | import { useQuery } from '@apollo/client';
2 | import React from 'react';
3 | import { gql } from '__generated__/gql';
4 | import AlertRegion from '../../../../../components/AlertRegion';
5 | import Badge, { BadgeColor } from '../../../../../components/Badge';
6 | import Spinner from '../../../../../components/Spinner';
7 |
8 | const GET_CATEGORY = gql(`
9 | query GetCategory($id: ID!) {
10 | category(id: $id) {
11 | id
12 | name
13 | }
14 | }
15 | `);
16 |
17 | export default function CategoryBadge(props: {
18 | categoryID: string,
19 | color?: BadgeColor
20 | }) {
21 | const { categoryID, color } = props;
22 | const { data, loading, error } = useQuery(GET_CATEGORY, {
23 | variables: {
24 | id: categoryID,
25 | },
26 | });
27 |
28 | if (loading) {
29 | return ;
30 | }
31 |
32 | if (error) {
33 | return (
34 | {error.message}
35 | );
36 | }
37 |
38 | return (
39 |
40 | {data?.category.name!}
41 |
42 | );
43 | }
44 |
45 | CategoryBadge.defaultProps = {
46 | color: 'blue',
47 | };
48 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Input.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | interface InputProps extends React.HTMLProps {
5 | onChange?: React.ChangeEventHandler
6 | }
7 |
8 | const Input = React.forwardRef((props: InputProps, ref: React.Ref) => {
9 | const { className } = props;
10 | return (
11 |
21 | );
22 | });
23 |
24 | interface InputLabelProps extends React.HTMLProps { }
25 | export function InputLabel(props: InputLabelProps) {
26 | const { children, className } = props;
27 | return (
28 |
31 | );
32 | }
33 |
34 | Input.defaultProps = {
35 | onChange: undefined,
36 | };
37 |
38 | export default Input;
39 |
--------------------------------------------------------------------------------
/monoid-py/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools"]
3 | build-backend = "setuptools.build_meta"
4 | [project]
5 | name = "monoid_pydev"
6 | version = "0.0.1a2"
7 | authors = [
8 | { name="Monoid, Inc.", email="support@monoid.co" },
9 | ]
10 | description = "Tools for building Monoid data silos."
11 | readme = "README.md"
12 | requires-python = ">=3.7"
13 | classifiers = [
14 | "Programming Language :: Python :: 3",
15 | "License :: OSI Approved :: MIT License",
16 | "Operating System :: OS Independent",
17 | ]
18 | dynamic = ["dependencies"]
19 |
20 | [project.urls]
21 | "Homepage" = "https://www.monoid.co"
22 | "Bug Tracker" = "https://github.com/monoid/monoid/issues"
23 |
24 | [tool.setuptools.dynamic]
25 | dependencies = {file = ["requirements.txt"]}
26 |
27 | [tool.bumpver]
28 | current_version = "0.0.1a2"
29 | version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
30 | commit_message = "bump version {old_version} -> {new_version}"
31 | commit = true
32 | tag = false
33 | push = false
34 |
35 | [tool.bumpver.file_patterns]
36 | "pyproject.toml" = [
37 | 'current_version = "{version}"',
38 | 'version = "{version}"',
39 | ]
40 | "README.md" = [
41 | "{version}",
42 | "{pep440_version}",
43 | ]
44 |
45 |
--------------------------------------------------------------------------------
/monoid-api/filestore/localstore/localstore.go:
--------------------------------------------------------------------------------
1 | package localstore
2 |
3 | import (
4 | "context"
5 | "io"
6 | "os"
7 | "path/filepath"
8 | "strings"
9 |
10 | "github.com/monoid-privacy/monoid/filestore"
11 | )
12 |
13 | type localFileStore struct {
14 | RootDir string
15 | }
16 |
17 | func NewLocalFileStore(rootDir string) filestore.FileStore {
18 | return &localFileStore{
19 | RootDir: rootDir,
20 | }
21 | }
22 |
23 | func safeJoin(root string, objName string) string {
24 | if strings.HasPrefix(objName, root+string(os.PathSeparator)) {
25 | return objName
26 | }
27 |
28 | return filepath.Join(root, objName)
29 | }
30 |
31 | func (ls *localFileStore) NewWriter(ctx context.Context, objectName string, segmentFile bool) (io.WriteCloser, string, error) {
32 | fp := filepath.Join(ls.RootDir, objectName)
33 | f, err := os.Create(fp)
34 |
35 | if err != nil {
36 | return nil, "", err
37 | }
38 |
39 | return f, objectName, nil
40 | }
41 |
42 | func (ls *localFileStore) NewReader(ctx context.Context, objectName string, segmentFile bool) (io.ReadCloser, error) {
43 | fp := safeJoin(ls.RootDir, objectName)
44 |
45 | f, err := os.Open(fp)
46 |
47 | if err != nil {
48 | return nil, err
49 | }
50 |
51 | return f, nil
52 | }
53 |
--------------------------------------------------------------------------------
/monoid-api/scanner/basicscanner/helpers.go:
--------------------------------------------------------------------------------
1 | package basicscanner
2 |
3 | import (
4 | "regexp"
5 | )
6 |
7 | func stringInSlice(a string, list []string) bool {
8 | for _, b := range list {
9 | if b == a {
10 | return true
11 | }
12 | }
13 | return false
14 | }
15 |
16 | func matchNameRule(name string, rules []nameRule) (nameRule, int) {
17 | for i, rule := range rules {
18 | if stringInSlice(name, rule.ColumnNames) {
19 | return rule, i
20 | }
21 | }
22 | return nameRule{}, -1
23 | }
24 |
25 | func anyMatches(rule tokenRule, values []string) bool {
26 | for _, value := range values {
27 | if rule.Tokens.Contains(value) {
28 | return true
29 | }
30 | }
31 | return false
32 | }
33 |
34 | // split on whitespace
35 | var tokenizer = regexp.MustCompile(`\W+`)
36 |
37 | // var space = regexp.MustCompile(`\s+`)
38 |
39 | // filtering out e.g. postgres connection commands
40 | var urlPassword = regexp.MustCompile(`((\/\/|%2F%2F)\S+(:|%3A))\S+(@|%40)`)
41 |
42 | func unique(arr []string) []string {
43 | keys := make(map[string]bool)
44 | list := []string{}
45 | for _, entry := range arr {
46 | if _, value := keys[entry]; !value {
47 | keys[entry] = true
48 | list = append(list, entry)
49 | }
50 | }
51 | return list
52 | }
53 |
--------------------------------------------------------------------------------
/monoid-py/monoid_pydev/logger/logger.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from typing import Optional
3 |
4 | from monoid_pydev.models.models import MonoidLogMessage, MonoidMessage
5 |
6 |
7 | def get_logger(name: Optional[str] = None):
8 | logger = logging.getLogger(name)
9 | logger.setLevel(logging.INFO)
10 |
11 | stream_handler = logging.StreamHandler()
12 | stream_handler.setFormatter(MonoidFormatter())
13 |
14 | logger.addHandler(stream_handler)
15 |
16 | return logger
17 |
18 |
19 | class MonoidFormatter(logging.Formatter):
20 | """
21 | Converts log messages into MonoidMessage json objects.
22 | """
23 |
24 | # Transforming Python log levels to Airbyte protocol log levels
25 | level_mapping = {
26 | logging.FATAL: "FATAL",
27 | logging.ERROR: "ERROR",
28 | logging.WARNING: "WARN",
29 | logging.INFO: "INFO",
30 | logging.DEBUG: "DEBUG",
31 | }
32 |
33 | def format(self, record) -> str:
34 | level = self.level_mapping.get(record.levelno, "INFO")
35 | message = super().format(record)
36 | return MonoidMessage(
37 | type="LOG",
38 | log=MonoidLogMessage(
39 | message=message
40 | )
41 | ).json()
42 |
--------------------------------------------------------------------------------
/monoid-api/download/handlers.go:
--------------------------------------------------------------------------------
1 | package download
2 |
3 | import (
4 | "context"
5 | "io"
6 | "net/http"
7 |
8 | "github.com/gorilla/mux"
9 | "github.com/monoid-privacy/monoid/config"
10 | "github.com/monoid-privacy/monoid/model"
11 | "github.com/rs/zerolog/log"
12 | )
13 |
14 | type DownloadHandler struct {
15 | Conf *config.BaseConfig
16 | }
17 |
18 | func (dh *DownloadHandler) HandleDownload(w http.ResponseWriter, r *http.Request) {
19 | vars := mux.Vars(r)
20 |
21 | id, ok := vars["id"]
22 | if !ok {
23 | w.WriteHeader(http.StatusNotFound)
24 | return
25 | }
26 |
27 | df := model.DownloadableFile{}
28 | if err := dh.Conf.DB.Where("id = ?", id).First(&df).Error; err != nil {
29 | w.WriteHeader(http.StatusNotFound)
30 | return
31 | }
32 |
33 | f, err := dh.Conf.FileStore.NewReader(context.Background(), df.StoragePath, false)
34 | if err != nil {
35 | w.WriteHeader(http.StatusNotFound)
36 | return
37 | }
38 |
39 | defer f.Close()
40 | w.Header().Set("Content-Disposition", "attachment; filename=\"result.tar.gz\"")
41 | w.Header().Set("Content-Type", "application/octet-stream")
42 |
43 | if _, err := io.Copy(w, f); err != nil {
44 | w.WriteHeader(http.StatusInternalServerError)
45 | log.Err(err).Msg("Error writing file")
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mysql/mysql_lib/spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "spec": {
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "type": "object",
5 | "properties": {
6 | "hostname": {
7 | "type": "string",
8 | "title": "Hostname",
9 | "order": 0,
10 | "description": "The hostname of the database"
11 | },
12 | "port": {
13 | "type": "number",
14 | "title": "Port",
15 | "order": 1,
16 | "description": "The port of the database"
17 | },
18 | "database": {
19 | "type": "string",
20 | "title": "Database",
21 | "description": "The database to connect to.",
22 | "order": 2
23 | },
24 | "username": {
25 | "type": "string",
26 | "title": "Username",
27 | "description": "The username for the database.",
28 | "order": 3
29 | },
30 | "password": {
31 | "type": "string",
32 | "secret": true,
33 | "title": "Password",
34 | "description": "The password for the database",
35 | "order": 4
36 | }
37 | },
38 | "required": [
39 | "username",
40 | "hostname",
41 | "password",
42 | "port",
43 | "database"
44 | ]
45 | }
46 | }
--------------------------------------------------------------------------------
/monoid-integrations/monoid-mariadb/mariadb_lib/spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "spec": {
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "type": "object",
5 | "properties": {
6 | "hostname": {
7 | "type": "string",
8 | "title": "Hostname",
9 | "order": 0,
10 | "description": "The hostname of the database"
11 | },
12 | "port": {
13 | "type": "number",
14 | "title": "Port",
15 | "order": 1,
16 | "description": "The port of the database"
17 | },
18 | "database": {
19 | "type": "string",
20 | "title": "Database",
21 | "description": "The database to connect to.",
22 | "order": 2
23 | },
24 | "username": {
25 | "type": "string",
26 | "title": "Username",
27 | "description": "The username for the database.",
28 | "order": 3
29 | },
30 | "password": {
31 | "type": "string",
32 | "secret": true,
33 | "title": "Password",
34 | "description": "The password for the database",
35 | "order": 4
36 | }
37 | },
38 | "required": [
39 | "username",
40 | "hostname",
41 | "password",
42 | "port",
43 | "database"
44 | ]
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Silos/SiloRoutes.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Navigate, Route, Routes } from 'react-router-dom';
3 | import NewSiloPage from './pages/NewSiloPage/NewSiloPage';
4 | import SiloIndex from './pages/SiloIndexPage/SiloIndex';
5 | import SiloPage from './pages/SiloPage/SiloPage';
6 |
7 | export default function SiloRoutes() {
8 | return (
9 |
10 | } />
11 | } />
12 |
13 | } />
14 | } />
15 |
16 | } />
17 |
26 | )}
27 | />
28 |
29 | } />
30 | } />
31 |
32 |
33 | );
34 | }
35 |
--------------------------------------------------------------------------------
/monoid-api/cmd/tools/loader/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "github.com/google/uuid"
8 | "github.com/joho/godotenv"
9 | "github.com/monoid-privacy/monoid/cmd"
10 | "github.com/monoid-privacy/monoid/cmd/tools/loader/loader"
11 | "github.com/monoid-privacy/monoid/config"
12 | "github.com/monoid-privacy/monoid/model"
13 | )
14 |
15 | func register(conf *config.BaseConfig) (model.OSSRegistration, error) {
16 | registration := model.OSSRegistration{}
17 | if err := conf.DB.First(®istration).Error; err != nil {
18 | registration.ID = uuid.NewString()
19 |
20 | if err := conf.DB.Create(®istration).Error; err != nil {
21 | return model.OSSRegistration{}, err
22 | }
23 | }
24 |
25 | conf.AnalyticsIngestor.Track("startup", ®istration.ID, map[string]interface{}{})
26 |
27 | return registration, nil
28 | }
29 |
30 | func main() {
31 | if len(os.Args) != 2 {
32 | fmt.Println("Usage ./loader [config directory]")
33 | return
34 | }
35 |
36 | _ = godotenv.Load()
37 |
38 | conf := cmd.GetBaseConfig(cmd.MigrateOSS)
39 | defer conf.AnalyticsIngestor.Close()
40 |
41 | if _, err := register(&conf); err != nil {
42 | panic("Error creating OSS registration.")
43 | }
44 |
45 | loader.LoadSpecs(&conf, os.Args[1])
46 | loader.LoadCategories(&conf, os.Args[1])
47 | }
48 |
--------------------------------------------------------------------------------
/monoid-api/workflow/activity/requestactivity/db_updates.go:
--------------------------------------------------------------------------------
1 | package requestactivity
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/monoid-privacy/monoid/model"
7 | )
8 |
9 | type UpdateRequestStatusArgs struct {
10 | RequestStatusID string
11 | Status model.RequestStatusType
12 | }
13 |
14 | // UpdateRequestStatusActivity updates the request status in the DB
15 | func (a *RequestActivity) UpdateRequestStatusActivity(
16 | ctx context.Context,
17 | args UpdateRequestStatusArgs,
18 | ) error {
19 | return a.Conf.DB.Model(&model.RequestStatus{}).Where(
20 | "id = ?",
21 | args.RequestStatusID,
22 | ).Update(
23 | "status",
24 | args.Status,
25 | ).Error
26 | }
27 |
28 | type BatchUpdateRequestStatusArgs struct {
29 | RequestID string
30 | SiloDefinitionID string
31 | Status model.RequestStatusType
32 | }
33 |
34 | func (a *RequestActivity) BatchUpdateRequestStatusActivity(
35 | ctx context.Context,
36 | args BatchUpdateRequestStatusArgs,
37 | ) error {
38 | return a.Conf.DB.Model(&model.RequestStatus{}).Where(
39 | "request_id = ?",
40 | args.RequestID,
41 | ).Where(
42 | "data_source_id IN (?)", a.Conf.DB.Model(&model.DataSource{}).Select("id").Where(
43 | "silo_definition_id = ?", args.SiloDefinitionID,
44 | ),
45 | ).Update("status", args.Status).Error
46 | }
47 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Breadcrumb.tsx:
--------------------------------------------------------------------------------
1 | import { ChevronRightIcon } from '@heroicons/react/24/solid';
2 | import React from 'react';
3 | import { Link } from 'react-router-dom';
4 | import { classNames } from '../utils/utils';
5 |
6 | interface BreadcrumbProps extends React.HTMLProps {
7 | links: {
8 | name: string,
9 | to: string,
10 | current?: boolean
11 | }[]
12 | }
13 |
14 | export default function Breadcrumb(props: BreadcrumbProps) {
15 | const { links, className } = props;
16 | return (
17 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/monoid-api/analytics/handlers.go:
--------------------------------------------------------------------------------
1 | package analytics
2 |
3 | import (
4 | "encoding/json"
5 | "net/http"
6 |
7 | "github.com/monoid-privacy/monoid/analytics/ingestor"
8 | )
9 |
10 | type AnalyticsHandler struct {
11 | Ingestor ingestor.Ingestor
12 | }
13 |
14 | type TrackPayload struct {
15 | UserID string `json:"userId"`
16 | Event string `json:"event"`
17 | Properties map[string]interface{} `json:"properties"`
18 | }
19 |
20 | func (h *AnalyticsHandler) HandleTrack(w http.ResponseWriter, r *http.Request) {
21 | payload := TrackPayload{}
22 | err := json.NewDecoder(r.Body).Decode(&payload)
23 | if err != nil {
24 | w.WriteHeader(http.StatusOK)
25 | return
26 | }
27 |
28 | h.Ingestor.Track(payload.Event, &payload.UserID, payload.Properties)
29 | w.WriteHeader(http.StatusOK)
30 | }
31 |
32 | type IdentifyPayload struct {
33 | UserID string `json:"userId"`
34 | Traits map[string]interface{} `json:"traits"`
35 | }
36 |
37 | func (h *AnalyticsHandler) HandleIdentify(w http.ResponseWriter, r *http.Request) {
38 | payload := IdentifyPayload{}
39 | err := json.NewDecoder(r.Body).Decode(&payload)
40 | if err != nil {
41 | w.WriteHeader(http.StatusOK)
42 | return
43 | }
44 |
45 | h.Ingestor.Identify(&payload.UserID, payload.Traits)
46 | w.WriteHeader(http.StatusOK)
47 | }
48 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Text.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | interface TextProps extends Omit, 'size'> {
5 | size?: 'xs' | 'sm' | 'md' | 'lg',
6 | em?: 'light' | 'normal' | 'bold'
7 | as?: 'p' | 'div'
8 | }
9 |
10 | export default function Text(props: TextProps) {
11 | const {
12 | children, as, className, size, em, ...rest
13 | } = props;
14 | let sizeCls = '';
15 | switch (size) {
16 | case 'xs':
17 | sizeCls = 'text-xs';
18 | break;
19 | case 'sm':
20 | sizeCls = 'text-sm';
21 | break;
22 | case 'md':
23 | sizeCls = 'text-md';
24 | break;
25 | case 'lg':
26 | sizeCls = 'text-lg';
27 | break;
28 | default:
29 | sizeCls = 'text-md';
30 | }
31 |
32 | let emCls = '';
33 | switch (em) {
34 | case 'light':
35 | emCls = 'text-gray-400';
36 | break;
37 | case 'normal':
38 | emCls = '';
39 | break;
40 | case 'bold':
41 | emCls = 'font-semibold';
42 | break;
43 | default:
44 | break;
45 | }
46 |
47 | return React.createElement(as!, {
48 | className: classNames(className, sizeCls, emCls),
49 | ...rest,
50 | }, children);
51 | }
52 |
53 | Text.defaultProps = {
54 | size: 'md',
55 | em: 'normal',
56 | as: 'div',
57 | };
58 |
--------------------------------------------------------------------------------
/docusaurus/src/css/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Any CSS included here will be global. The classic template
3 | * bundles Infima by default. Infima is a CSS framework designed to
4 | * work well for content-centric websites.
5 | */
6 |
7 | /* You can override the default Infima variables here. */
8 | :root {
9 | --ifm-heading-color: #000b34;
10 | --ifm-font-color-base: #000b34;
11 | --ifm-color-primary: #244cec;
12 | --ifm-color-primary-dark: #29784c;
13 | --ifm-color-primary-darker: #277148;
14 | --ifm-color-primary-darkest: #205d3b;
15 | --ifm-color-primary-light: #33925d;
16 | --ifm-color-primary-lighter: #359962;
17 | --ifm-color-primary-lightest: #3cad6e;
18 | --ifm-footer-background-color: #000b34;
19 | --ifm-code-font-size: 95%;
20 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
21 | }
22 |
23 | /* For readability concerns, you should choose a lighter palette in dark mode. */
24 | [data-theme='dark'] {
25 | --ifm-heading-color: #ffffff;
26 | --ifm-font-color-base: #ffffff;
27 | --ifm-color-primary: #244cec;
28 | --ifm-color-primary-dark: #21af90;
29 | --ifm-color-primary-darker: #1fa588;
30 | --ifm-color-primary-darkest: #1a8870;
31 | --ifm-color-primary-light: #29d5b0;
32 | --ifm-color-primary-lighter: #32d8b4;
33 | --ifm-color-primary-lightest: #4fddbf;
34 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
35 | }
36 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Spinner.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | export default function Spinner(props: { size?: 'sm' | 'md' | 'lg', color?: 'primary' | 'white' }) {
5 | const { size, color } = props;
6 | let sizeClasses = 'h-5 w-5';
7 |
8 | switch (size) {
9 | case 'sm':
10 | sizeClasses = 'h-3 w-3';
11 | break;
12 | case 'lg':
13 | sizeClasses = 'h-10 w-10';
14 | break;
15 | case 'md':
16 | default:
17 | sizeClasses = 'h-5 w-5';
18 | break;
19 | }
20 |
21 | let colorClasses = 'text-indigo-600';
22 | switch (color) {
23 | case 'white':
24 | colorClasses = 'text-gray-100';
25 | break;
26 | case 'primary':
27 | default:
28 | colorClasses = 'text-indigo-600';
29 | }
30 |
31 | return (
32 |
36 | );
37 | }
38 |
39 | Spinner.defaultProps = {
40 | size: 'md',
41 | color: 'primary',
42 | };
43 |
--------------------------------------------------------------------------------
/monoid-api/cmd/worker/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os"
6 |
7 | "github.com/monoid-privacy/monoid/cmd"
8 | mworker "github.com/monoid-privacy/monoid/cmd/worker/worker"
9 | "github.com/monoid-privacy/monoid/workflow"
10 | "github.com/rs/zerolog"
11 | "go.temporal.io/sdk/client"
12 | "go.temporal.io/sdk/worker"
13 | zerologadapter "logur.dev/adapter/zerolog"
14 | "logur.dev/logur"
15 | )
16 |
17 | func main() {
18 | conf := cmd.GetBaseConfig(nil)
19 | defer conf.AnalyticsIngestor.Close()
20 |
21 | logger := logur.LoggerToKV(zerologadapter.New(zerolog.New(os.Stdout).Level(zerolog.InfoLevel)))
22 |
23 | // Create the client object just once per process
24 | c, err := client.Dial(client.Options{
25 | HostPort: os.Getenv("TEMPORAL"),
26 | Logger: logger,
27 | })
28 |
29 | if err != nil {
30 | log.Fatalln("unable to create Temporal client", err)
31 | }
32 |
33 | defer c.Close()
34 |
35 | w := worker.New(c, workflow.DockerRunnerQueue, worker.Options{
36 | MaxConcurrentActivityExecutionSize: 5,
37 | MaxConcurrentWorkflowTaskExecutionSize: 5,
38 | })
39 |
40 | mworker.RegisterWorkerWorkflowActivities(
41 | w,
42 | mworker.DefaultActivites(&conf),
43 | mworker.DefaultWorkflows(&conf),
44 | )
45 |
46 | // Start listening to the Task Queue
47 | err = w.Run(worker.InterruptCh())
48 | if err != nil {
49 | log.Fatalln("unable to start Worker", err)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/monoid-ui/src/utils/use-popper.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/tailwindlabs/headlessui/blob/main/packages/playground-react/utils/hooks/use-popper.ts
2 |
3 | import {
4 | RefCallback, useRef, useCallback, useMemo,
5 | } from 'react';
6 | import { createPopper, Options } from '@popperjs/core';
7 |
8 | /**
9 | * Example implementation to use Popper: https://popper.js.org/
10 | */
11 | export default function usePopper(
12 | options?: Partial,
13 | ): [RefCallback, RefCallback] {
14 | const reference = useRef(null);
15 | const popper = useRef(null);
16 |
17 | const cleanupCallback = useRef(() => { });
18 |
19 | const instantiatePopper = useCallback(() => {
20 | if (!reference.current) return;
21 | if (!popper.current) return;
22 |
23 | if (cleanupCallback.current) cleanupCallback.current();
24 |
25 | cleanupCallback.current = createPopper(reference.current, popper.current, options).destroy;
26 | }, [reference, popper, cleanupCallback, options]);
27 |
28 | return useMemo(
29 | () => [
30 | (referenceDomNode) => {
31 | reference.current = referenceDomNode;
32 | instantiatePopper();
33 | },
34 | (popperDomNode) => {
35 | popper.current = popperDomNode;
36 | instantiatePopper();
37 | },
38 | ],
39 | [reference, popper, instantiatePopper],
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/monoid-ui/src/contexts/WorkspaceContext.tsx:
--------------------------------------------------------------------------------
1 | import { ApolloError, useQuery } from '@apollo/client';
2 | import React, { useMemo } from 'react';
3 | import { useParams } from 'react-router-dom';
4 | import { gql } from '__generated__/gql';
5 | import { Workspace } from '../lib/models';
6 |
7 | interface WorkspaceContextType {
8 | workspace?: Workspace
9 | loading: boolean,
10 | error?: ApolloError,
11 | }
12 |
13 | const initVal: WorkspaceContextType = {
14 | workspace: undefined,
15 | loading: true,
16 | error: undefined,
17 | };
18 |
19 | const WorkspaceContext = React.createContext(initVal);
20 | export default WorkspaceContext;
21 |
22 | const WORKSPACE_QUERY = gql(`
23 | query WorkspaceQuery($id: ID!) {
24 | workspace(id: $id) {
25 | id
26 | name
27 | onboardingComplete
28 | }
29 | }
30 | `);
31 |
32 | export function WorkspaceProvider(props: { children: React.ReactNode }) {
33 | const { children } = props;
34 | const { id } = useParams<{ id: string }>();
35 | const { data, loading, error } = useQuery(WORKSPACE_QUERY, {
36 | variables: {
37 | id: id!,
38 | },
39 | });
40 |
41 | const providerVal = useMemo(() => ({
42 | workspace: data?.workspace as Workspace,
43 | loading,
44 | error,
45 | }), [data, loading]);
46 |
47 | return (
48 |
49 | {children}
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/docs/understand/technical/architecture-overview.md:
--------------------------------------------------------------------------------
1 | # Architecture Overview
2 |
3 | At a high level, Monoid consists of a React UI, a Go webapp server, a Temporal service.
4 | The Temporal service manages jobs to run actions on data silos; for more information about
5 | how Monoid interfaces with the data silo connectors, see documentation on the Monoid Protocol.
6 |
7 | ## Technical Stack
8 |
9 | ### Monoid Core Backend
10 |
11 | * Go 1.18.8
12 | * API: GraphQL
13 | * Databases: PostgreSQL
14 | * Orchestration: Temporal
15 |
16 | The Monoid core backend can be found in `monoid-api`.
17 |
18 | The `monoid-api/requests` package handles user data deletion/export request automation. The open-source PII scanner can be found in `monoid-api/scanner`; its design was inspired by that of Andrew Kane's open-source PII scanner [here](https://github.com/ankane/pdscan).
19 |
20 | The GraphQL API schema is in `monoid-api/schema`. DB models can be found in `monoid-api/models`, while GraphQL API resolver functions can be found in `monoid-api/resolver`.
21 |
22 | ### Connectors
23 |
24 | Connectors can be written in any language. Connectors written by the Monoid team are generally written in Python 3.7.6.
25 |
26 | Connectors can be found in `monoid-integrations`, while tools to create connectors can be found in `monoid-py`.
27 |
28 | ### Frontend
29 |
30 | * Typescript
31 | * Web Framework: React
32 |
33 | The UI can be found in `monoid-ui`.
34 |
35 | ### Additional Tools
36 |
37 | * Containerization: Docker
38 |
--------------------------------------------------------------------------------
/monoid-api/config/config.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/monoid-privacy/monoid/analytics/ingestor"
7 | "github.com/monoid-privacy/monoid/filestore"
8 | "github.com/monoid-privacy/monoid/monoidprotocol"
9 | "go.temporal.io/sdk/client"
10 | "gorm.io/gorm"
11 | )
12 |
13 | type BaseConfig struct {
14 | DB *gorm.DB
15 | WebURL string
16 | ProtocolFactory monoidprotocol.MonoidProtocolFactory
17 | FileStore filestore.FileStore
18 | TempStorePath string
19 | TemporalClient client.Client
20 | AnalyticsIngestor ingestor.Ingestor
21 | EncryptionKey []byte
22 | ResourcePath string
23 | }
24 |
25 | func (c BaseConfig) PreFlightHandler(next http.Handler) http.Handler {
26 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27 | w.Header().Set("Connection", "keep-alive")
28 | w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
29 | w.Header().Set("Access-Control-Allow-Origin", c.WebURL)
30 | w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, DELETE, PUT")
31 | w.Header().Set("Access-Control-Allow-Headers", "content-type, Authorization")
32 | w.Header().Set("Access-Control-Max-Age", "86400")
33 | w.Header().Set("Access-Control-Allow-Credentials", "true")
34 | if r.Method == http.MethodOptions {
35 | w.WriteHeader(http.StatusOK)
36 | return
37 | }
38 |
39 | w.Header().Set("Access-Control-Allow-Origin", c.WebURL)
40 | next.ServeHTTP(w, r)
41 | })
42 | }
43 |
--------------------------------------------------------------------------------
/monoid-ui/src/cache/helpers.ts:
--------------------------------------------------------------------------------
1 | import { FieldMergeFunction, FieldReadFunction } from '@apollo/client';
2 |
3 | export const paginationRead: (fieldName: string) => FieldReadFunction = (
4 | (fieldName) => (existing, { args }) => {
5 | const offset = args?.offset || 0;
6 | const limit = args?.limit || 0;
7 |
8 | const res = existing && {
9 | ...existing,
10 | [fieldName]: existing[fieldName]?.slice(offset, offset + limit),
11 | };
12 |
13 | return res;
14 | }
15 | );
16 |
17 | export const paginationMerge: (fieldName: string, countName: string) => FieldMergeFunction = (
18 | (fieldName, countName) => (existing, incoming, { args }) => {
19 | if (!incoming) {
20 | return existing;
21 | }
22 |
23 | const offset = args?.offset || 0;
24 | const limit = args?.limit || 0;
25 | let merged = (existing && existing[fieldName]) ? existing[fieldName].slice(0) : undefined;
26 |
27 | if (incoming[fieldName]) {
28 | if (!merged) {
29 | merged = [];
30 | }
31 |
32 | for (let i = 0; i < incoming[fieldName].length; i += 1) {
33 | merged[offset + i] = incoming[fieldName][i];
34 | }
35 |
36 | if (incoming[fieldName].length < limit) {
37 | merged = merged.slice(0, offset + incoming[fieldName].length);
38 | }
39 | }
40 |
41 | const r = {
42 | ...incoming,
43 | [countName]: incoming[countName] || (existing && existing[countName]),
44 | [fieldName]: merged,
45 | };
46 |
47 | return r;
48 | }
49 | );
50 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Card.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { classNames } from '../utils/utils';
3 |
4 | interface CardProps extends React.HTMLProps {
5 | innerClassName?: string,
6 | }
7 |
8 | export default function Card(props: CardProps) {
9 | const {
10 | className, innerClassName, children, ...rest
11 | } = props;
12 |
13 | return (
14 |
15 |
16 | {children}
17 |
18 |
19 | );
20 | }
21 |
22 | Card.defaultProps = {
23 | innerClassName: '',
24 | };
25 |
26 | interface CardDividerProps extends React.HTMLProps { }
27 |
28 | export function CardDivider(props: CardDividerProps) {
29 | const { className, ...rest } = props;
30 |
31 | return (
32 |
37 | );
38 | }
39 |
40 | interface CardHeaderProps extends React.HTMLProps { }
41 |
42 | export function CardHeader(props: CardHeaderProps) {
43 | const { children, className, ...rest } = props;
44 |
45 | return (
46 | {children}
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/monoid-ui/src/pages/Onboarding/components/RequestStepBody.tsx:
--------------------------------------------------------------------------------
1 | import { useMutation } from '@apollo/client';
2 | import Card from 'components/Card';
3 | import PageHeader from 'components/PageHeader';
4 | import { EXECUTE_REQUEST } from 'graphql/requests_queries';
5 | import NewRequestForm from 'pages/Requests/pages/NewRequestPage/components/NewRequestForm';
6 | import Text from 'components/Text';
7 | import React from 'react';
8 |
9 | export default function RequestBody(props: { onSuccess: (reqId: string) => void }) {
10 | const [executeReq] = useMutation(EXECUTE_REQUEST);
11 | const { onSuccess } = props;
12 |
13 | return (
14 | <>
15 |
16 |
17 | Now that you've set up your silo and sources, you can create a test request.
18 | You should try creating a query request first, as you'll be able to see the results
19 | more clearly. We'll also automatically execute the request for you
20 | (by default, future requests will get executed after you manually approve them).
21 |
22 |
23 | {
26 | executeReq({
27 | variables: {
28 | id: req.id!,
29 | },
30 | }).then(() => {
31 | onSuccess(req.id!);
32 | });
33 | }}
34 | />
35 |
36 | >
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/docs/monoid-open-source-quick-start/scan-data-sources.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2.5
3 | ---
4 |
5 | # Scan Data Sources
6 |
7 | Once you've connected a data silo, you can scan the silo for its associated data models to create your data map.
8 |
9 | To do so, navigate to `Configuration > Data Silos` on the left sidebar, and click on the silo that you want to scan (you'll need to [create the silo](monoid-open-source-quick-start/connect-data-silos.md) first). Then, click the `Scan` button on the top right corner to queue the scan job; based on the silo, the job may take a minute or two to complete.
10 |
11 | Once the scan is complete, you'll receive alerts for each detected data source; you can navigate to the `Alerts` tab on the data silo's page (or on the left sidebar) to approve or reject each detected data source.
12 |
13 | 
14 |
15 | The data sources you accept, along with their properties, will show up in the `Data Sources` tab of the data silo's page, and can be used to construct your data map.
16 |
17 | ## Scheduled Scans
18 |
19 | Monoid can detect structural changes in connected silos' data sources (e.g. a schema change in a DB table) through scheduled scans. To run scheduled scans, navigate to the `Scans` tab and change the `Scan Frequency` under `Scan Settings`. You can track scheduled scans in the `Scans` tab on the left sidebar or on your silo's page. Scans that detect changes will create alerts on the `Alerts` tab; the changes won't go into effect until you approve the corresponding alerts.
20 |
21 | 
22 |
--------------------------------------------------------------------------------
/docs/connector-catalog/connector-list.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 2
3 | sidebar_label: "Connector List"
4 | ---
5 |
6 | # Connector List
7 |
8 | This is a list of connectors currently available (either in the OSS repo, through a Monoid Cloud subscription, or in beta as a custom integration with existing customers) on Monoid. We're building new connectors every week; if you'd like access to a beta/premium connector, please reach out to jagath@monoid.co. If you would like a new connector to be created by the Monoid team, please create a Github issue or email jagath@monoid.co.
9 |
10 | | Connector | Available in Open-Source | Beta/Premium Connector |
11 | | --- | --- | --- |
12 | | Google BigQuery | ✓ | |
13 | | Amazon Redshift | ✓ | |
14 | | Microsoft SQL Server | ✓ | |
15 | | Snowflake |✓ | |
16 | | MariaDB | ✓ | |
17 | | Postgres | ✓ | |
18 | | Intercom | ✓ | |
19 | | Mixpanel | ✓ | |
20 | | MySQL | ✓ | |
21 | | Datadog | | ✓ |
22 | | Amazon S3 | | ✓ |
23 | | Slack | | ✓ |
24 | | Firebase | | ✓ |
25 | | Singlestore | | ✓ |
26 | | Cassandra | | ✓ |
27 | | Sentry | | ✓ |
28 | | Airtable | | ✓ |
29 | | Airbyte | | ✓ |
30 | | Algolia | | ✓ |
31 | | Okta | | ✓ |
32 | | Mailchimp | | ✓ |
33 | | Asana | | ✓ |
34 | | Heap | | ✓ |
35 | | MongoDB | | ✓ |
36 | | Gong | | ✓ |
37 | | Lever | | ✓ |
38 | | Iterable | | ✓ |
39 | | Braze | | ✓ |
40 | | Outreach.io | | ✓ |
41 | | Hubspot | | ✓ |
42 | | Salesforce | | ✓ |
43 | | Zendesk | | ✓ |
44 | | Segment | | ✓ |
45 | | Facebook Ads | | ✓ |
46 | | Twilio | | ✓ |
47 | | Amplitude | | ✓ |
48 | | Stripe | | ✓ |
49 | | Google Ads | | ✓ |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/monoid-api/cmd/worker/worker/worker.go:
--------------------------------------------------------------------------------
1 | package worker
2 |
3 | import (
4 | "github.com/monoid-privacy/monoid/config"
5 | "github.com/monoid-privacy/monoid/workflow"
6 | "github.com/monoid-privacy/monoid/workflow/activity"
7 | "github.com/monoid-privacy/monoid/workflow/activity/requestactivity"
8 | "github.com/monoid-privacy/monoid/workflow/requestworkflow"
9 | "go.temporal.io/sdk/worker"
10 | )
11 |
12 | func DefaultActivites(conf *config.BaseConfig) []interface{} {
13 | a := activity.Activity{
14 | Conf: conf,
15 | }
16 |
17 | ra := requestactivity.RequestActivity{
18 | Conf: conf,
19 | }
20 |
21 | return []interface{}{
22 | a.ValidateDataSiloDef,
23 | a.DetectDataSources,
24 | a.FindOrCreateJob,
25 | a.UpdateJobStatus,
26 | ra.UpdateRequestStatusActivity,
27 | ra.FindDBSilos,
28 | ra.ProcessRequestResults,
29 | ra.RequestStatusActivity,
30 | ra.StartSiloRequestActivity,
31 | ra.BatchUpdateRequestStatusActivity,
32 | }
33 | }
34 |
35 | func DefaultWorkflows(conf *config.BaseConfig) []interface{} {
36 | mwf := workflow.Workflow{
37 | Conf: conf,
38 | }
39 |
40 | rmwf := requestworkflow.RequestWorkflow{
41 | Conf: conf,
42 | }
43 |
44 | return []interface{}{
45 | mwf.ValidateDSWorkflow,
46 | mwf.DetectDSWorkflow,
47 | rmwf.ExecuteRequestWorkflow,
48 | rmwf.ExecuteSiloRequestWorkflow,
49 | }
50 | }
51 |
52 | func RegisterWorkerWorkflowActivities(
53 | w worker.Worker,
54 | activities []interface{},
55 | workflows []interface{},
56 | ) {
57 |
58 | for _, a := range activities {
59 | w.RegisterActivity(a)
60 | }
61 |
62 | for _, wf := range workflows {
63 | w.RegisterWorkflow(wf)
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/docs/start-here.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_position: 1
3 | sidebar_label: "Start Here"
4 | slug: /
5 | ---
6 |
7 | # Welcome to Monoid Docs
8 |
9 | ### For Monoid cloud users
10 |
11 | Monoid Cloud is now available - you can get started [here](https://app.monoid.co).
12 |
13 | ### For Monoid Open Source users
14 |
15 | Check out the [Monoid Open Source QuickStart](monoid-open-source-quick-start/deploy-monoid.md) to get up-and-running. Then learn how to [deploy](/category/deploy-monoid-open-source) Monoid Open Source in your cloud infrastructure (deployment guides and one-click deploy for major providers are currently in development).
16 |
17 | Browse the [connector catalog](/category/connector-catalog) to find the connector you want. If the connector is not yet supported on Monoid Open Source, [build your own connector](/category/build-a-connector), submit an issue, or [sign up for a Monoid Cloud](https://monoid.co) to get custom connectors from the Monoid Team.
18 |
19 | To get help with Monoid deployments, [email us](mailto:jagath@monoid.co) or join our [Slack](https://join.slack.com/t/monoidworkspace/shared_invite/zt-1nlqb5si8-JXLu9sJuZBwgMr3YsXnyLw).
20 |
21 | ### For Monoid contributors
22 |
23 | To contribute to Monoid code, connectors, and documentation, refer to our [contribution guide](contribute-to-monoid/guide).
24 |
25 | ### Here to Learn?
26 |
27 | If you'd like to learn more about how Monoid works, check out [Understand Monoid](/category/understand-monoid). If you're a non-technical professional (e.g. legal/compliance) looking to learn more about whether Monoid could work for your initiatives, please see our [Non-technical Overview](understand/nontechnical.md).
28 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/PageHeader.tsx:
--------------------------------------------------------------------------------
1 | import React, { HTMLProps } from 'react';
2 | import { classNames } from '../utils/utils';
3 | import { H1, H2 } from './Headers';
4 | import Text from './Text';
5 |
6 | interface PageHeaderProps extends Omit, 'title'> {
7 | title: React.ReactNode
8 | subtitle?: React.ReactNode
9 | actionItem?: React.ReactNode
10 | level?: 'top' | 'second'
11 | }
12 |
13 | export default function PageHeader(props: PageHeaderProps) {
14 | const {
15 | className, title, subtitle, actionItem, level, ...divProps
16 | } = props;
17 |
18 | let header: React.ReactNode;
19 |
20 | switch (level) {
21 | case 'second':
22 | header = (
23 |
24 | {title}
25 |
26 | );
27 | break;
28 | case 'top':
29 | default:
30 | header = (
31 |
32 | {title}
33 |
34 | );
35 | }
36 |
37 | return (
38 |
39 |
40 | {header}
41 | {subtitle
42 | && (
43 |
44 | {subtitle}
45 |
46 | )}
47 |
48 |
49 |
50 | {actionItem}
51 |
52 |
53 | );
54 | }
55 |
56 | PageHeader.defaultProps = {
57 | actionItem: undefined,
58 | subtitle: undefined,
59 | level: 'top',
60 | };
61 |
--------------------------------------------------------------------------------
/monoid-api/filestore/encryptedstore/encryptedstore.go:
--------------------------------------------------------------------------------
1 | package localstore
2 |
3 | import (
4 | "context"
5 | "crypto/rand"
6 | "crypto/sha256"
7 | "io"
8 |
9 | "github.com/minio/sio"
10 | "github.com/monoid-privacy/monoid/filestore"
11 | "golang.org/x/crypto/hkdf"
12 | )
13 |
14 | type encryptedFileStore struct {
15 | filestore filestore.FileStore
16 | key []byte
17 | }
18 |
19 | func NewEncryptedFileStore(filestore filestore.FileStore, key []byte) filestore.FileStore {
20 | return &encryptedFileStore{
21 | filestore: filestore,
22 | key: key,
23 | }
24 | }
25 |
26 | func (fs *encryptedFileStore) NewWriter(
27 | ctx context.Context,
28 | objectName string,
29 | segmentFile bool,
30 | ) (wr io.WriteCloser, fp string, err error) {
31 | writer, filePath, err := fs.filestore.NewWriter(ctx, objectName, segmentFile)
32 | if err != nil {
33 | return nil, "", err
34 | }
35 |
36 | defer func() {
37 | if err != nil {
38 | wr.Close()
39 | fp = ""
40 | wr = nil
41 | }
42 | }()
43 |
44 | var nonce [32]byte
45 | if _, err = io.ReadFull(rand.Reader, nonce[:]); err != nil {
46 | return nil, "", err
47 | }
48 |
49 | var key [32]byte
50 | kdf := hkdf.New(sha256.New, key[:], nonce[:], nil)
51 | if _, err = io.ReadFull(kdf, key[:]); err != nil {
52 | return nil, "", err
53 | }
54 |
55 | writer, err = sio.EncryptWriter(writer, sio.Config{Key: key[:]})
56 | if err != nil {
57 | return nil, "", err
58 | }
59 |
60 | return writer, filePath, nil
61 | }
62 |
63 | func (ls *encryptedFileStore) NewReader(ctx context.Context, objectName string, segmentFile bool) (io.ReadCloser, error) {
64 | return ls.filestore.NewReader(ctx, objectName, segmentFile)
65 | }
66 |
--------------------------------------------------------------------------------
/monoid-api/cmd/tools/discovery/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "os"
7 |
8 | "github.com/docker/docker/client"
9 | "github.com/joho/godotenv"
10 | "github.com/monoid-privacy/monoid/specimport"
11 | "gopkg.in/yaml.v3"
12 | )
13 |
14 | func main() {
15 | _ = godotenv.Load()
16 |
17 | if len(os.Args) != 3 {
18 | fmt.Println("Usage: ./discovery [manifest_file] [out_file]")
19 | return
20 | }
21 |
22 | // Get the manifest spec
23 | fileName := os.Args[1]
24 | f, err := os.Open(fileName)
25 |
26 | if err != nil {
27 | panic(err)
28 | }
29 |
30 | defer f.Close()
31 |
32 | // Get the initial integrations from the spec
33 | integrations := []specimport.IntegrationManifestEntry{}
34 | if err := yaml.NewDecoder(f).Decode(&integrations); err != nil {
35 | panic(err)
36 | }
37 |
38 | dockerCli, err := client.NewClientWithOpts(client.FromEnv)
39 | if err != nil {
40 | panic(err)
41 | }
42 |
43 | dockerCli.NegotiateAPIVersion(context.Background())
44 |
45 | // Run the docker command to get the json schema for the silos
46 | specs := []*specimport.IntegrationFullSpecEntry{}
47 | for _, integration := range integrations {
48 | spec, err := specimport.GetFullSpec(&integration, dockerCli)
49 | if err != nil {
50 | fmt.Printf("Error parsing integration %s: %v\n", integration.Name, err)
51 | continue
52 | }
53 |
54 | specs = append(specs, spec)
55 | }
56 |
57 | // Write the enriched schema back.
58 | outfile, err := os.Create(os.Args[2])
59 | if err != nil {
60 | panic(err)
61 | }
62 |
63 | defer outfile.Close()
64 |
65 | err = yaml.NewEncoder(outfile).Encode(&specs)
66 | if err != nil {
67 | panic(err)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/monoid-api/dataloader/silo_definitions.go:
--------------------------------------------------------------------------------
1 | package dataloader
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | "github.com/graph-gophers/dataloader"
8 | "github.com/monoid-privacy/monoid/model"
9 | "github.com/rs/zerolog/log"
10 | )
11 |
12 | // SiloDefinition wraps the associated dataloader
13 | func SiloDefinition(ctx context.Context, id string) (*model.SiloDefinition, error) {
14 | loaders := For(ctx)
15 | thunk := loaders.SiloDefinitionLoader.Load(ctx, dataloader.StringKey(id))
16 | result, err := thunk()
17 | if err != nil {
18 | return nil, err
19 | }
20 | return result.(*model.SiloDefinition), nil
21 | }
22 |
23 | // siloDefinitions gets all the silo definnitions by ids in keys
24 | func (c *Reader) siloDefinitions(ctx context.Context, keys dataloader.Keys) []*dataloader.Result {
25 | // read all requested users in a single query
26 | ids := make([]string, len(keys))
27 | for ix, key := range keys {
28 | ids[ix] = key.String()
29 | }
30 |
31 | silos := []*model.SiloDefinition{}
32 |
33 | if err := c.conf.DB.Where(
34 | "id IN ?",
35 | ids,
36 | ).Find(&silos).Error; err != nil {
37 | log.Err(err).Msg("Error finding silos.")
38 | }
39 |
40 | siloMap := map[string]*model.SiloDefinition{}
41 | for _, c := range silos {
42 | siloMap[c.ID] = c
43 | }
44 |
45 | // return users in the same order requested
46 | output := make([]*dataloader.Result, len(keys))
47 | for index, k := range keys {
48 | res, ok := siloMap[k.String()]
49 | if ok {
50 | output[index] = &dataloader.Result{Data: res, Error: nil}
51 | } else {
52 | output[index] = &dataloader.Result{Data: nil, Error: fmt.Errorf("could not find silo")}
53 | }
54 | }
55 |
56 | return output
57 | }
58 |
--------------------------------------------------------------------------------
/monoid-api/resolver/silo_definition_helpers.go:
--------------------------------------------------------------------------------
1 | package resolver
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/monoid-privacy/monoid/model"
7 | "github.com/monoid-privacy/monoid/monoidprotocol"
8 | "github.com/monoid-privacy/monoid/workflow"
9 | "go.temporal.io/sdk/client"
10 | )
11 |
12 | type validateResult struct {
13 | success bool
14 | message string
15 | }
16 |
17 | func (r *Resolver) validateSiloDef(ctx context.Context, workflowID string, siloDefinition model.SiloDefinition) (*validateResult, error) {
18 | options := client.StartWorkflowOptions{
19 | ID: workflowID,
20 | TaskQueue: workflow.DockerRunnerQueue,
21 | }
22 |
23 | // Start the Workflow
24 | sf := workflow.Workflow{
25 | Conf: r.Conf,
26 | }
27 |
28 | confSecret, err := siloDefinition.Config.ValueBytes()
29 | if err != nil {
30 | return nil, err
31 | }
32 |
33 | we, err := r.Conf.TemporalClient.ExecuteWorkflow(ctx, options, sf.ValidateDSWorkflow, workflow.ValidateDSArgs{
34 | SiloSpecID: siloDefinition.SiloSpecificationID,
35 | Config: confSecret,
36 | })
37 | if err != nil {
38 | return nil, err
39 | }
40 |
41 | // Get the results
42 | var res monoidprotocol.MonoidValidateMessage
43 | err = we.Get(ctx, &res)
44 | if err != nil {
45 | return nil, err
46 | }
47 |
48 | if res.Status == monoidprotocol.MonoidValidateMessageStatusFAILURE {
49 | msg := "An error occurred while validating connection information."
50 |
51 | if res.Message != nil {
52 | msg = *res.Message
53 | }
54 |
55 | return &validateResult{
56 | success: false,
57 | message: msg,
58 | }, nil
59 | }
60 |
61 | return &validateResult{
62 | success: true,
63 | message: "",
64 | }, nil
65 | }
66 |
--------------------------------------------------------------------------------
/monoid-ui/src/components/Toggle.tsx:
--------------------------------------------------------------------------------
1 | import { Switch } from '@headlessui/react';
2 | import React from 'react';
3 | import { classNames } from '../utils/utils';
4 |
5 | export default function Toggle(props: {
6 | className?: string,
7 | checked: boolean,
8 | size?: 'md' | 'lg'
9 | onChange: (c: boolean) => void
10 | }) {
11 | const {
12 | className, checked, onChange, size,
13 | } = props;
14 |
15 | let switchSize = '';
16 | let handleSize = '';
17 | let translate = '';
18 | if (size === 'md') {
19 | switchSize = 'h-6 w-11';
20 | handleSize = 'h-5 w-5';
21 | translate = 'translate-x-5';
22 | } else if (size === 'lg') {
23 | switchSize = 'h-10 w-16';
24 | handleSize = 'h-9 w-9';
25 | translate = 'translate-x-6';
26 | }
27 |
28 | return (
29 |
39 | Use setting
40 |
48 |
49 | );
50 | }
51 |
52 | Toggle.defaultProps = {
53 | className: '',
54 | size: 'md',
55 | };
56 |
--------------------------------------------------------------------------------