Adds Harvesting and Anonymization components

parent afc5c1a1
Makefile
*.DS_Store
.settings
.buildpath
.project
tmp/*
/vendor
composer.phar
/app/config/local
/app/config/staging
/app/config/production
/app/config/packages
/bootstrap/compiled.php
/installed/*
!/installed/.gitkeep
app/config/workbench.php
public/packages
workbench
node_modules/
app/storage/app
# IDE dependant
.idea
.idea/*
\ No newline at end of file
language: php
services: mysql
php:
- "5.6"
- "7.0"
env:
- DB=mysql
before_script:
- mysql -e 'CREATE DATABASE core_test;'
- sudo hostname test.travis-ci.org
- pecl install dbase
- echo "extension = dbase.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer install
script:
- phpunit
\ No newline at end of file
# tdt/core
[![Join the chat at https://gitter.im/tdt/core](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tdt/core?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Latest Stable Version](https://poser.pugx.org/tdt/core/version.png)](https://packagist.org/packages/tdt/core)
[![Build Status](https://travis-ci.org/tdt/core.svg?branch=development)](https://travis-ci.org/tdt/core) [![Dependency Status](https://www.versioneye.com/php/tdt:core/badge.png)](https://www.versioneye.com/php/tdt:core)
The DataTank core is the framework in which the main application of The DataTank is built. The DataTank is a web application that publishes data to URIs in web readable formats. This means that you provide a nice JSON, XML, PHP, ... serialization on a certain URI of data that resides somewhere in a CSV, XLS, XML, JSON, SHP, ... file or any other machine readable data container. In short, it provides an instant REST API on top of any machine readable data.
## Installation
[Installation docs](http://docs.thedatatank.com/5.12/installation)
## Front end
Run `npm install` when upgrading to 6.6
`gulp` will build all static assets for production
`gulp serve` will watch `*.js` & `*.scss`
`gulp js` will minify the jQuery source
`gulp webpack` will build the Vue project (currently only for homepage)
# Read more
If you want to read more about The DataTank project visit our [website](http://thedatatank.com) or take a look at our [documentation](http://docs.thedatatank.com).
The DataTank is free software (AGPL, © 2011,2012 iRail NPO, 2012 Open Knowledge Belgium) to create an API for data in no time.
Any questions? Add a support issue!
<?php
namespace Tdt\Core\Analytics;
/**
* GA Tracker class.
*
* @copyright (C) 2011, 2014 by OKFN Belgium vzw/asbl
* @license AGPLv3
* @author Jan Vansteenlandt <jan@okfn.be>
* @author appreciate.be
*/
class GaTracker implements TrackerInterface
{
private $IGNORE = ['api', 'discovery'];
public function track($request, $tracker_id)
{
$path = $request->path();
$extension = '';
if (strpos($path, '.') !== false) {
$uri_parts = explode('.', $request->path());
$extension = strtolower(array_pop($uri_parts));
$path = implode('', $uri_parts);
} else {
$extension = 'html';
}
// Get some meta-data from the definition to add to the GA as a dimension
$definitions = \App::make('Tdt\Core\Repositories\Interfaces\DefinitionRepositoryInterface');
$definition = $definitions->getByIdentifier($path);
$license = 'Not provided';
$theme = 'Not provided';
if (!empty($definition['rights'])) {
$license = $definition['rights'];
}
if (!empty($definition['theme'])) {
$theme = $definition['theme'];
}
// Get the target audience and category.
$segments = $request->segments();
if (count($segments) >= 2 && !in_array($segments[0], $this->IGNORE)) {
// The URL of the GA
$url = 'http://www.google-analytics.com/collect';
// The version of the Google Analytics Measurement Protocol.
$data['v'] = 1;
// The tracker ID.
$data['tid'] = $tracker_id;
// GA requires a user ID, but since all requests are anonymous
// we generate a unique string to use as ID.
$data['cid'] = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
// The type of 'hit', in this case we use pageview.
$data['t'] = 'pageview';
// The url to track, required when using 'pageview' as type.
$data['dp'] = $path;
$data['cd1'] = $extension;
$data['cd2'] = $theme;
$data['cd3'] = $license;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, utf8_encode(http_build_query($data)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
}
}
}
<?php
namespace Tdt\Core\Analytics;
interface TrackerInterface
{
public function track($request, $tracker_id);
}
<?php
namespace Tdt\Core\Analytics;
use Illuminate\Support\ServiceProvider;
class TrackerServiceProvider extends ServiceProvider
{
public function register()
{
\App::bind(
'Tdt\Core\Analytics\TrackerInterface',
'Tdt\Core\Analytics\GaTracker'
);
}
}
<?php
namespace Tdt\Core;
use \Tdt\Core\Repositories\Interfaces\DefinitionRepositoryInterface;
/**
* ApiController
*
* @copyright (C) 2011, 2014 by OKFN Belgium vzw/asbl
* @license AGPLv3
* @author Jan Vansteenlandt <jan@okfn.be>
*/
abstract class ApiController extends Controller
{
protected $definition;
public function __construct(DefinitionRepositoryInterface $definition)
{
$this->definition = $definition;
}
public function handle($uri)
{
$uri = ltrim($uri, '/');
// Delegate the request based on the used http method
$method = \Request::getMethod();
switch ($method) {
case 'PUT':
return $this->put($uri);
break;
case 'GET':
return $this->get($uri);
break;
case 'POST':
case 'PATCH':
return $this->patch($uri);
break;
case 'DELETE':
return $this->delete($uri);
break;
case 'HEAD':
return $this->head($uri);
break;
default:
// Method not supported
\App::abort(405, "The HTTP method '$method' is not supported by this resource ($uri).");
break;
}
}
public function get($uri)
{
\App::abort(405, 'The HTTP method GET is not supported by this resource.');
}
public function put($uri)
{
\App::abort(405, 'The HTTP method PUT is not supported by this resource.');
}
public function patch($uri)
{
\App::abort(405, 'The HTTP method PATCH is not supported by this resource.');
}
public function head($uri)
{
\App::abort(405, 'The HTTP method HEAD is not supported by this resource.');
}
public function delete($uri)
{
\App::abort(405, 'The HTTP method DELETE is not supported by this resource.');
}
}
<?php
namespace Tdt\Core\Auth;
/**
* Auth Controller
* @copyright (C) 2011, 2014 by OKFN Belgium vzw/asbl
* @license AGPLv3
* @author Michiel Vancoillie <michiel@okfn.be>
*/
class Auth extends \Controller
{
private static $user;
private static $password;
/**
* Check if user meets permissions required to do the request, otherwise prompt login
*/
public static function requirePermissions($permissions = null)
{
// Make sure permissions is an array
if (!is_array($permissions)) {
$permissions = array($permissions);
}
// First check the permissions of the group 'everyone
try {
// Get the group
$group = \Sentry::findGroupByName('everyone');
// Get the group permissions
$groupPermissions = $group->getPermissions();
foreach ($permissions as $permission) {
if (!empty($groupPermissions[$permission]) && $groupPermissions[$permission] == 1) {
// Everyone has access
return true;
} else {
break;
}
}
} catch (\Cartalyst\Sentry\Groups\GroupNotFoundException $e) {
// Do nothing, proceed other checks
}
// Authenticate
self::logIn();
if (\Sentry::check()) {
// Check permissions
if (self::hasAccess($permissions)) {
return true;
} else {
\App::abort(403, "The authenticated user hasn't got the permissions for this action.");
}
} else {
\App::abort(401, 'Authentication is required.');
}
}
/**
* Log's user in
*/
protected static function logIn()
{
// Fix basic auth on some servers;
self::basicAuth();
// Show login form for browser requests
if (empty(self::$user)) {
if (\Sentry::check()) {
return true;
} else {
// Redirect to login
header('Location: ' . \URL::to('api/admin/login?return=' . \Request::path()));
die();
}
} else {
// Basic auth, TODO: remove check
if (\App::environment() != 'testing') {
header('WWW-Authenticate: Basic');
header('HTTP/1.0 401 Unauthorized');
}
}
if (isset(self::$user)) {
try {
// Set login credentials
$credentials = array(
'email' => self::$user,
'password' => self::$password,
);
// Try to authenticate the user
$user = \Sentry::authenticate($credentials, false);
} catch (\Cartalyst\Sentry\Users\LoginRequiredException $e) {
\App::abort(401, 'Authentication is required.');
} catch (\Cartalyst\Sentry\Users\PasswordRequiredException $e) {
\App::abort(401, 'Authentication is required.');
} catch (\Cartalyst\Sentry\Users\WrongPasswordException $e) {
\App::abort(401, 'Authentication is required, username and password mismatch.');
} catch (\Cartalyst\Sentry\Users\UserNotFoundException $e) {
\App::abort(401, 'Authentication is required, username and password mismatch.');
} catch (\Cartalyst\Sentry\Users\UserNotActivatedException $e) {
\App::abort(403, 'Authentication is required, user is not activated.');
}
// The following is only required if throttle is enabled
catch (\Cartalyst\Sentry\Throttling\UserSuspendedException $e){
\App::abort(403, 'Authentication is required, user is suspended.');
} catch (\Cartalyst\Sentry\Throttling\UserBannedException $e) {
\App::abort(403, 'Authentication is required, user is banned.');
}
} else {
\App::abort(401, 'Authentication is required.');