GithubHelp home page GithubHelp logo

salesforce / oss-request Goto Github PK

View Code? Open in Web Editor NEW
8.0 5.0 5.0 1.01 MB

License: BSD 3-Clause "New" or "Revised" License

Scala 74.71% HTML 22.86% Shell 0.09% Batchfile 0.99% CSS 0.13% JavaScript 0.98% Procfile 0.24%

oss-request's Introduction

OSS Request

This is a flexible system that enables users to submit OSS requests, then assign tasks to those requests, and manage those tasks.

Metadata Schema

The request system is driven by a metadata definition which includes system groups and the prototypes for tasks. Check out an example. For production use set the METADATA_GIT_URI and METADATA_GIT_SSH_KEY env vars so the metadata can be externalized from this source. Here the properties that need to be defined in the metadata file:

  • name (string) The name of the program

  • description (string) Description of the program

  • groups (object, required) - Defines the groups where the key is the identifier of the group and the value is an array of string email addresses. There must be a group with the key admin but additional groups can also be defined.

  • services (object) - Defines the urls for service names in key-values on the the object

  • reports (object) - Named search queries

    • a_unique_id (object)
      • title (string, required) - Title displayed in the site navigation
      • query (object) - Query parameters
        • state (enum) - Request state: IN_PROGRESS | ON_HOLD | CANCELLED | COMPLETED
        • program (string) - Program identifier
        • data (object) - Task data to search for
  • tasks (object, required) - Defines the tasks where the key is the identifier of the task and the value is an object defining the prototype for a task. There must be a task with the key start but additional tasks should also be defined. A task prototype object has the following properties:

    • label (string, required) - Displayed in the header of the task view

    • type (enum, required) - The type of task INPUT | ACTION | APPROVAL

    • info (string, required) - Displayed in the body of the task view

    • form (object, required for INPUT tasks) - Definition of the input form defined by Alpaca

    • completable_by (object) - Defines who can complete the task. If not set, the task will be assigned to the request owner. If set, here are the properties:

      • type (enum) - Either GROUP | EMAIL | SERVICE
      • value (string) - For GROUP must be a defined group. For EMAIL the value can be set to an email but if not specified the UI will prompt the user to enter an email. For SERVICE the value must be a service name defined in the services object.
    • task_events (object) - Defines event handlers on the task with these properties:

      • type (enum, required) - Currently only STATE_CHANGE is supported and triggers when the task's state changes

      • value (enum, required) - Any task state: IN_PROGRESS | ON_HOLD | CANCELLED | COMPLETED

      • action (object, required) - The action to perform when the event is triggered. Here are the properties:

        • type (enum, required) - Currently only CREATE_TASK is supported
        • value (string) - The identifier of the task
      • criteria (object) - Defines critera for when the action should be run

        • type (enum, required) - Currently only FIELD_VALUE is supported and allows filtering on a field's value
        • value (string, required) - Matches a field name and value, e.g. foo==bar
    • approval_conditions (array) - Strings with the possible approval conditions that can be applied to this task

Your metadata can define multiple programs by nesting the above structure in an object with a program identifier, like:

{
    "my_program": {
        "name": "My Program",
        ...
    }
}

Tasks Assigned to Services

The default (and currently only) security mechanism for services is Pre-Shared Keys (PSK). To configure a service's PSK, sent the an env named PSK_HEXSTRING where the HEXSTRING is an uppercase hex representation of the service's URL.

This sends the the value psk MY_SERVICE_PSK in the AUTHORIZATION HTTP header when talking to the service.

A service must be accessible at a given URL and implement two HTTP APIs:

Create Task with POST:

{
    "request": {
        "program": "default",
        "slug": "asdf",
        "name": "A Request"
    },
    "task": {
        "id": 1,
        "url": "http://asdf.com/request/asdf",
        "label": "A Task",
        "data": {
            ...
        },
        "dependencies": {
            "task_name": {
                ...
            }
        }
    }
}

Respond with 201 - Created:

{
    "state": "IN_PROGRESS|ON_HOLD|CANCELLED|COMPLETED",
    "url": "http://asdf.com/asdf",
    "data": {
        ...
    }
}

Fetch State with GET: ?url=http://asdf.com/asdf

Respond with 200 - Ok:

{
    "state": "IN_PROGRESS|ON_HOLD|CANCELLED|COMPLETED",
    "url": "http://asdf.com/asdf",
    "data": {
        ...
    }
}

Architecture

This application is built with:

  • Play Framework 2.6
  • Scala
  • Postgres
  • Reactive I/O (Non-Blocking)

Deploy on Heroku

Local Dev Setup

  1. Install Java 8

  2. Install Postgres

  3. Create local Postgres databases:

     $ createdb
     $ psql
     # CREATE ROLE ossrequest LOGIN password 'password' SUPERUSER;
     # CREATE DATABASE ossrequest ENCODING 'UTF8' OWNER ossrequest;
     # CREATE DATABASE "ossrequest-test" ENCODING 'UTF8' OWNER ossrequest;
    

Run the Web App

Optionally test with an OAuth provider

Salesforce:

export OAUTH_CLIENT_ID=<YOUR CLIENT ID>
export OAUTH_CLIENT_SECRET=<YOUR CLIENT SECRET>
export AUTH_PROVIDER=oauth
export OAUTH_PROVIDER=salesforce

GitHub:

export OAUTH_CLIENT_ID=<YOUR CLIENT ID>
export OAUTH_CLIENT_SECRET=<YOUR CLIENT SECRET>
export AUTH_PROVIDER=oauth
export OAUTH_PROVIDER=github
  1. Start the web app:

     $ ./sbt ~run
    

To run with a SAML provider

export AUTH_PROVIDER=oauth
export SAML_ENTITY_ID="YOUR SAML ENTITY ID"
export SAML_METADATA_URL="YOUR SAML METADATA URL"
  1. Start the web app with https enabled:

      $ ./sbt -Dhttps.port=9443
    

Run the Tests

Optionally config to test OAuth:

export TEST_SALESFORCE_OAUTH_CLIENT_ID=<YOUR CLIENT ID>
export TEST_SALESFORCE_OAUTH_CLIENT_SECRET=<YOUR CLIENT SECRET>
export TEST_SALESFORCE_USERNAME=<YOUR TEST USERNAME>
export TEST_SALESFORCE_PASSWORD=<YOUR TEST PASSWORD>

export TEST_GITHUB_OAUTH_CLIENT_ID=<YOUR CLIENT ID>
export TEST_GITHUB_OAUTH_CLIENT_SECRET=<YOUR CLIENT SECRET>
export TEST_GITHUB_TOKEN=<YOUR_GITHUB_TEST_TOKEN>

Optionally config to test SparkPost:

export SPARKPOST_API_KEY=<YOUR SPARKPOST API KEY>
export SPARKPOST_DOMAIN=<YOUR SPARKPOST DOMAIN>

To test external Metadata, create a metadata file on GitHub, create a public/private key pair, and add a read-only deploy key to the repo. Set env vars, like:

export TEST_METADATA_GIT_URI='[email protected]:foo/oss-request-test.git'
export TEST_METADATA_GIT_FILE=metadata.json
export TEST_METADATA_GIT_SSH_KEY=$(< id_rsa)

To test with SAML:

export SAML_ENTITY_ID="YOUR SAML ENTITY ID"
export SAML_METADATA_URL="YOUR SAML METADATA URL"
  1. Run all of the tests continuously:

     $ ./sbt ~test
    

oss-request's People

Contributors

jimjag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

oss-request's Issues

Allow Task Reassignment

Admins and Task owners should be able to reassign them. A notification should be sent to the new owner(s).

Add Email Provider

Pick a Heroku Addon we want to support out-of-the-box in prod. Default to some STDOUT thing in dev.

Add the email logic to the DAO.

Selectable Start Task

Metadata on program defines start tasks. If there is more than one, then the user is prompted to select the task.

Program Description

On new request, instead of a drop down, use a selectable list and provide a program description in each item. Description should come from metadata and support markdown.

URLs for Comments

Emails about comments should have a URL that pulls up the comments.

Alphabetize /requests list

When viewing the list of requests, I would like the list to be alphabetized so I can easily find a specific request in the list.

Race Condition in Metadata Fetch

If two or more concurrent fetches for metadata happen, one can fail because if (!baseDir.exists()) { - the dir exists but the git clone hasn't completed.

Add Security

The UI and the DAO should implement record security. For example:

  • Only admins can complete a request
  • Only admins or an assigned user should be able to update a task

Version Info in Prototype

Will enable migrations or the app to understand the task persisted prototype when the schema changes.

Post-Approval Tasks

Provide a way to create a new task post approval on some time-frame. Like every 6 months add a new IP Approval task.

Search /requests list

When viewing the /requests list, I would like a search box that filters requests by name so I can more easily find the request I am interested in.

Filtering could be accomplished with a client-side javascript filter that hides non-matching rows.

Filter /requests list

When viewing the /requests list, I would like a way to filter the requests by status so I can quickly find the request I am looking for.

Example: A dropdown for status - Approved, Conditionally Approved, In Progress, Denied

Links in Metadata

Provide a way (maybe markdown) for putting links in the metadata.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.