Use travelynx.conf for configuration and secrets

This avoids having to specify secrets in the environment, where they can leak
easily.
This commit is contained in:
Daniel Friesel 2019-04-13 12:17:19 +02:00
parent 61b1ef398e
commit 80a6317ac5
7 changed files with 70 additions and 53 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/travelynx.conf

View file

@ -36,8 +36,9 @@ Debian 9 system, though setup on other distribution should be similar.
* Create a postgres user for travelynx: `sudo -u postgres createuser -P travelynx`
(enter password when prompted)
* Create the database: `sudo -u postgres createdb -O travelynx travelynx`
* Initialize the database: `TRAVELYNX_DB_HOST=... TRAVELYNX_DB_NAME=... `
`TRAVELYNX_DB_USER=... TRAVELYNX_DB_PASSWORD=... perl index.pl setup`
* Copy `examples/travelynx.conf` to the application root directory
(the one in which `index.pl` resides) and configure it
* Initialize the database: `perl index.pl database setup`
Your server also needs to be able to send mail. Set up your MTA of choice and
make sure that the sendmail binary can be used for outgoing mails. Mail

23
examples/travelynx.conf Normal file
View file

@ -0,0 +1,23 @@
{
cache => {
schedule => '/var/cache/travelynx/iris',
realtime => '/var/cache/travelynx/iris-rt',
},
db => {
host => 'localhost',
database => 'travelynx',
user => 'travelynx',
password => die("Changeme!"),
},
hypnotoad => {
accepts => 100,
clients => 10,
listen => [ 'http://127.0.0.1:8093' ],
pid_file => '/tmp/travelynx.pid',
workers => 2,
spare => 2,
},
secrets => [
die("Changeme!"),
],
};

View file

@ -16,19 +16,6 @@ WorkingDirectory=/srv/www/travelynx
Environment=LANG=en_US.UTF-8
Environment=TRAVELYNX_DB_NAME=travelynx
Environment=TRAVELYNX_DB_HOST=localhost
Environment=TRAVELYNX_DB_PORT=5432
Environment=TRAVELYNX_DB_USER=travelynx
Environment=TRAVELYNX_DB_PASSWORD= ! CHANGEME !
Environment=TRAVELYNX_SECRETS= ! CHANGEME !
Environment=TRAVELYNX_WORKERS=2
Environment=TRAVELYNX_LISTEN=http://127.0.0.1:8093
Environment=TRAVELYNX_IRIS_CACHE=/var/cache/dbf/iris
Environment=TRAVELYNX_IRISRT_CACHE=/var/cache/dbf/iris-rt
[Install]
WantedBy=multi-user.target

View file

@ -17,18 +17,6 @@ use Travelynx::Helper::Sendmail;
our $VERSION = qx{git describe --dirty} || 'experimental';
my $cache_iris_main = Cache::File->new(
cache_root => $ENV{TRAVELYNX_IRIS_CACHE} // '/tmp/dbf-iris-main',
default_expires => '6 hours',
lock_level => Cache::File::LOCK_LOCAL(),
);
my $cache_iris_rt = Cache::File->new(
cache_root => $ENV{TRAVELYNX_IRISRT_CACHE} // '/tmp/dbf-iris-realtime',
default_expires => '70 seconds',
lock_level => Cache::File::LOCK_LOCAL(),
);
sub check_password {
my ( $password, $hash ) = @_;
@ -66,27 +54,18 @@ sub get_station {
sub startup {
my ($self) = @_;
if ( $ENV{TRAVELYNX_SECRETS} ) {
$self->secrets( [ split( qr{:}, $ENV{TRAVELYNX_SECRETS} ) ] );
}
push( @{ $self->commands->namespaces }, 'Travelynx::Command' );
$self->defaults( layout => 'default' );
$self->config(
hypnotoad => {
accepts => $ENV{TRAVELYNX_ACCEPTS} // 100,
clients => $ENV{TRAVELYNX_CLIENS} // 10,
listen => [ $ENV{TRAVELYNX_LISTEN} // 'http://*:8093' ],
pid_file => $ENV{TRAVELYNX_PID_FILE} // '/tmp/travelynx.pid',
workers => $ENV{TRAVELYNX_WORKERS} // 2,
spare => $ENV{TRAVELYNX_SPARE} // 2,
},
);
$self->types->type( json => 'application/json; charset=utf-8' );
$self->plugin('Config');
if ( $self->config->{secrets} ) {
$self->secrets( $self->config->{secrets} );
}
$self->plugin(
authentication => {
autoload_user => 1,
@ -116,6 +95,30 @@ sub startup {
$self->defaults( layout => 'default' );
$self->attr(
cache_iris_main => sub {
my ($self) = @_;
return Cache::File->new(
cache_root => $self->app->config->{cache}->{schedule},
default_expires => '6 hours',
lock_level => Cache::File::LOCK_LOCAL(),
);
}
);
$self->attr(
cache_iris_rt => sub {
my ($self) = @_;
return Cache::File->new(
cache_root => $self->app->config->{cache}->{realtime},
default_expires => '70 seconds',
lock_level => Cache::File::LOCK_LOCAL(),
);
}
);
$self->attr(
action_type => sub {
return {
@ -321,12 +324,13 @@ sub startup {
$self->attr(
dbh => sub {
my ($self) = @_;
my $config = $self->app->config;
my $dbname = $ENV{TRAVELYNX_DB_NAME} // 'travelynx_dev';
my $host = $ENV{TRAVELYNX_DB_HOST} // 'localhost';
my $port = $ENV{TRAVELYNX_DB_PORT} // '5432';
my $user = $ENV{TRAVELYNX_DB_USER};
my $pw = $ENV{TRAVELYNX_DB_PASSWORD};
my $dbname = $config->{db}->{database};
my $host = $config->{db}->{host} // 'localhost';
my $port = $config->{db}->{port} // 5432;
my $user = $config->{db}->{user};
my $pw = $config->{db}->{password};
return DBI->connect(
"dbi:Pg:dbname=${dbname};host=${host};port=${port}",
@ -593,8 +597,8 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
$station = $station_matches[0][0];
my $status = Travel::Status::DE::IRIS->new(
station => $station,
main_cache => $cache_iris_main,
realtime_cache => $cache_iris_rt,
main_cache => $self->app->cache_iris_main,
realtime_cache => $self->app->cache_iris_rt,
lookbehind => 20,
datetime => DateTime->now( time_zone => 'Europe/Berlin' )
->subtract( minutes => $lookbehind ),

View file

@ -12,11 +12,11 @@ use Email::Simple;
sub new {
my ($class) = @_;
return bless({}, $class);
return bless( {}, $class );
}
sub custom {
my ($self, $to, $subject, $body) = @_;
my ( $self, $to, $subject, $body ) = @_;
my $reg_mail = Email::Simple->create(
header => [
@ -28,7 +28,8 @@ sub custom {
body => encode( 'utf-8', $body ),
);
if ($ENV{TRAVELYNX_DB_NAME} =~ m{travelynx_dev}) {
if ( $self->app->config->{db}->{database} =~ m{travelynx_dev} ) {
# Do not send mail in dev mode
say "sendmail to ${to}: ${subject}\n\n${body}";
return 1;

View file

@ -23,7 +23,7 @@
<nav class="deep-purple">
<div class="nav-wrapper container">
<a href="/" class="brand-logo left"><%= $ENV{TRAVELYNX_DB_NAME} =~ m{travelynx_dev} ? 'develynx' : 'travelynx' %></a>
<a href="/" class="brand-logo left"><%= app->config->{db}->{database} =~ m{travelynx_dev} ? 'develynx' : 'travelynx' %></a>
<ul id="nav-mobile" class="right">
% if (is_user_authenticated()) {
<li class="<%= navbar_class('/history') %>"><a href='/history' title="History"><i class="material-icons">history</i></a></li>