Skip to content

đź“ť A headless, multitenant dynamic content platform powered by Rails, GraphQL and Elasticsearch

License

Notifications You must be signed in to change notification settings

cortex-cms/cortex

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

263f793 Â· May 31, 2017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cortex CMS Build Status Code Climate Test Coverage Documentation Status

Cortex CMS Logo

Cortex CMS is a multitenant identity, content distribution/management and reporting platform built by the Content Enablement team at CareerBuilder. Its purpose is to provide central infrastructure for next-generation applications; exposing a single point of management while enabling quicker build-out of new software.

Cortex follows a decentralized, API-only architecture - it is not built like Wordpress or Drupal, which are considered monolithic, all-in-one solutions.

Table of Contents

Setup

Environment

Copy and rename the example .env.example file as .env and modify it to match your environment.

For a rudimentary setup, these variables should be configured:

  • Execute $ bundle exec rails secret twice to generate both an APP_SECRET and DEVISE_SECRET
  • If the superuser isn't used for the app databases, the DATABASE_USERNAME and DATABASE_PASSWORD should be set accordingly.
  • Set HOST to the local Web server's root URL to properly configure Fog (local asset storage)

Dependencies

System

OS X
  • Install the Xcode Command Line tools:
$ xcode-select --install
  • Install all Cortex system-wide dependencies (and the readline Ruby/byebug build dependency) using Homebrew from the Brewfile via $ brew install $(cat Brewfile|grep -v "#")
  • Install Ruby via rbenv or rvm.
  • Enable system agents:
$ ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents
$ ln -sfv /usr/local/opt/elasticsearch/*.plist ~/Library/LaunchAgents
$ ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents

and start them with brew services:

$ brew services start postgresql
$ brew services start elasticsearch
$ brew services start redis

or launchctl:

$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.elasticsearch.plist
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
Linux
  • Install all Cortex system-wide dependencies (and the readline Ruby/byebug build dependency) using your distribution's package manager (pacman, apt-get, yum, etc). For example, with Ubuntu's apt-get:
$ apt-get install libreadline6-dev postgresql postgresql-contrib redis-server openjdk-8-jre imagemagick jpegoptim ghostscript

Ubuntu and Redhat/Fedora do not have an official elasticsearch package - you must use Elasticsearch's repository or follow these instructions. The same goes for phantomjs. Build from source or use a PPA. Other Linux distributions likely have these as prebuilt packages in their official or user repositories.

  • Install Ruby via rbenv or rvm.
  • Enable system agents using your distribution's service manager frontend, which is likely systemd's frontend, systemctl:
$ systemctl enable postgresql
$ systemctl enable elasticsearch
$ systemctl enable redis

and start them with systemctl:

$ systemctl start postgresql
$ systemctl start elasticsearch
$ systemctl start redis

Application

  • Install Bundler and its dependencies:
$ gem install bundler && bundle install
  • Install node dependencies (including bower) and use bower-rails's rake task to install dependencies:
$ npm install && bundle exec rake bower:install:development

Database

  • Create databases:
$ bundle exec rake db:create
  • Initialize the schema:
$ bundle exec rake db:schema:load
  • Seed database with a top-level tenant, the superuser, Advice & Resources categories, ONET occupation/industry codes, and Custom Content data, then rebuild the ElasticSearch index:
$ bundle exec rake db:seed
$ bundle exec rake cortex:create_categories
$ bundle exec rake cortex:onet:fetch_and_provision
$ bundle exec rake cortex:core:db:reseed
$ bundle exec rake cortex:rebuild_indexes

Server

Start Cortex, Sidekiq and live rebuild of Webpack scripts via Foreman:

$ foreman start -f Procfile.dev

The admin interface should now be accessible locally on port 3000. To access Cortex as superadmin, login as admin@cortexcms.org with password welcome1.

Deployment

To use an automated tool to deploy the server, set this environmental variable:

CI=true

This will suppress Bower's interactive request to enable insights/metrics reporting, which normally prevents the CI process from continuing.

Additionally, deploying the development environment as a non-local server will require an additional environmental variable be set:

DEPLOYED=true

This will configure various things, such as dotenv to behave normally in a deployed scenario.

Running Test Suite

Initialize the test database:

$ RAILS_ENV=test bundle exec rake db:schema:load db:seed cortex:create_categories cortex:onet:fetch_and_provision cortex:core:db:reseed
$ RAILS_ENV=test bundle exec rake cortex:rebuild_indexes

To run Ruby and JS specs, utilize:

$ RAILS_ENV=test bundle exec rake spec
$ RAILS_ENV=test bundle exec rake spec:javascript

API

Documentation

Cortex's live API documentation is available via Swagger. This contains specific endpoints, parameters, and response models.

SwaggerUI is provided at http://docs.api.cbcortex.com/.

Swagger Endpoints are available at http://api.cbcortex.com/api/v1/swagger_doc.json.

Resources

Note: most resources are treated as 'paranoid' - that is, data is never truly deleted in the system - only archived.

Tenants act as a nested set and are the foundation of the channel-focused content distribution mechanism of Cortex, and allow data to be segregated throughout the system. Tenancy is currently very limited in scope. For example, users are directly tied to a tenant, and content can only be associated with a tenant via an inflexible content -> user -> tenant relationship. This will be expanded soon.

Users are for authorization and authentication. They currently lack roles, except for the ability to enable/disable admin access.

Media covers any potential file-type to be stored in or linked to by the Cortex. This includes:

  • Images
  • Audio
  • Video
  • Youtube Links
  • Documents
  • Text

When Media is consumed anywhere within the system, the two pieces of content become tied, and the Media cannot be deleted without the reference removed in the consuming piece of content.

Posts serve as a packaged distribution medium consisting of other content. They can be categorized, assigned to an occupation, and contain media of any format.

The posts endpoint also includes other posts-specific functionality, such as post filters and post tags.

Categories act as a nested set, living in a tree-like structure with parents and children. Cortex's API provides both this hierarchy and a flat list of categories, with a minimum depth as an optional parameter. These are currently unable to be manipulated via the admin interface, only directly within the database.

Occupations act as a nested set of Industries with specific Occupations (with SOC codes) beneath them. They utilize the ONET database, and are intended to eventually power intelligent content recommendations. See the cortex:onet rake task for specifics.

Localizations/locales provide YAML/JSON-formatted translations for consuming applications.

Applications contain credentials for OAuth applications that consume Cortex.

Bulk Jobs is the generic interface for uploads processed in bulk for any compatible resource, i.e. users, posts and media.

Documents are an incredibly generic piece of content, consisting only of raw text. They are intended to be made more specific by other resources, i.e. snippets and webpages.

Snippets build ontop of a generic Document, and are intended to be HTML sections on a webpage.

Webpages group together snippets, and correspond to a destination URL, and contain various additional metadata to power a dynamic, editable webpage.

Consuming Cortex

Authorization

Cortex's API utilizes OAuth2 for Authentication and Authorization. Client Credentials and Authorization Code grant types are supported. Want to get up and running quickly with OAuth? Use Cortex's Ruby client or OmniAuth strategy for Client Credentials and Authorization Code grants, respectively.

Review the optional_scopes in Cortex's Doorkeeper config to determine the available scopes, and the API Resource classes to determine where they're required.

Before an application can consume any data, OAuth credentials must be created for the consuming application in the 'Applications' section of the Cortex admin interface.

Content

Content can be consumed from a feed or via the resource's endpoint directly. Use the cortex-client gem to easily consume any content resource and use it in your application.

Localizations

Localizations can be consumed via the client or via i18n-backend-cortex, which allows easy localization for Rails applications.

Webpages and Snippets

Webpages/Snippets can be consumed via the client or via the content-snippets-view and content-snippets libraries, which need to be configured and hosted in order to be consumed.

Exceptions

If a consuming or companion application would like to produce Cortex-equivalent exceptions, use the cortex-exceptions gem.

Applications Using Cortex

Troubleshooting

  • For OS X / homebrew users: Run which node to ensure node is properly linked. The path shown should match homebrew's default installation path (run which brew to reveal this). If its not, then run brew link node and follow the instructions.

Contributing

Anyone and everyone is encouraged to fork Cortex and submit pull requests, propose new features and create issues.

Review CONTRIBUTING for complete instructions before you submit a pull request or feature proposal.

License

Cortex utilizes the Apache 2.0 License. See LICENSE for details.

Copyright

Copyright (c) 2016 CareerBuilder, LLC.