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` * Create a postgres user for travelynx: `sudo -u postgres createuser -P travelynx`
(enter password when prompted) (enter password when prompted)
* Create the database: `sudo -u postgres createdb -O travelynx travelynx` * Create the database: `sudo -u postgres createdb -O travelynx travelynx`
* Initialize the database: `TRAVELYNX_DB_HOST=... TRAVELYNX_DB_NAME=... ` * Copy `examples/travelynx.conf` to the application root directory
`TRAVELYNX_DB_USER=... TRAVELYNX_DB_PASSWORD=... perl index.pl setup` (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 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 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=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] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View file

@ -17,18 +17,6 @@ use Travelynx::Helper::Sendmail;
our $VERSION = qx{git describe --dirty} || 'experimental'; 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 { sub check_password {
my ( $password, $hash ) = @_; my ( $password, $hash ) = @_;
@ -66,27 +54,18 @@ sub get_station {
sub startup { sub startup {
my ($self) = @_; my ($self) = @_;
if ( $ENV{TRAVELYNX_SECRETS} ) {
$self->secrets( [ split( qr{:}, $ENV{TRAVELYNX_SECRETS} ) ] );
}
push( @{ $self->commands->namespaces }, 'Travelynx::Command' ); push( @{ $self->commands->namespaces }, 'Travelynx::Command' );
$self->defaults( layout => 'default' ); $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->types->type( json => 'application/json; charset=utf-8' );
$self->plugin('Config');
if ( $self->config->{secrets} ) {
$self->secrets( $self->config->{secrets} );
}
$self->plugin( $self->plugin(
authentication => { authentication => {
autoload_user => 1, autoload_user => 1,
@ -116,6 +95,30 @@ sub startup {
$self->defaults( layout => 'default' ); $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( $self->attr(
action_type => sub { action_type => sub {
return { return {
@ -321,12 +324,13 @@ sub startup {
$self->attr( $self->attr(
dbh => sub { dbh => sub {
my ($self) = @_; my ($self) = @_;
my $config = $self->app->config;
my $dbname = $ENV{TRAVELYNX_DB_NAME} // 'travelynx_dev'; my $dbname = $config->{db}->{database};
my $host = $ENV{TRAVELYNX_DB_HOST} // 'localhost'; my $host = $config->{db}->{host} // 'localhost';
my $port = $ENV{TRAVELYNX_DB_PORT} // '5432'; my $port = $config->{db}->{port} // 5432;
my $user = $ENV{TRAVELYNX_DB_USER}; my $user = $config->{db}->{user};
my $pw = $ENV{TRAVELYNX_DB_PASSWORD}; my $pw = $config->{db}->{password};
return DBI->connect( return DBI->connect(
"dbi:Pg:dbname=${dbname};host=${host};port=${port}", "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]; $station = $station_matches[0][0];
my $status = Travel::Status::DE::IRIS->new( my $status = Travel::Status::DE::IRIS->new(
station => $station, station => $station,
main_cache => $cache_iris_main, main_cache => $self->app->cache_iris_main,
realtime_cache => $cache_iris_rt, realtime_cache => $self->app->cache_iris_rt,
lookbehind => 20, lookbehind => 20,
datetime => DateTime->now( time_zone => 'Europe/Berlin' ) datetime => DateTime->now( time_zone => 'Europe/Berlin' )
->subtract( minutes => $lookbehind ), ->subtract( minutes => $lookbehind ),

View file

@ -12,11 +12,11 @@ use Email::Simple;
sub new { sub new {
my ($class) = @_; my ($class) = @_;
return bless({}, $class); return bless( {}, $class );
} }
sub custom { sub custom {
my ($self, $to, $subject, $body) = @_; my ( $self, $to, $subject, $body ) = @_;
my $reg_mail = Email::Simple->create( my $reg_mail = Email::Simple->create(
header => [ header => [
@ -28,7 +28,8 @@ sub custom {
body => encode( 'utf-8', $body ), 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 # Do not send mail in dev mode
say "sendmail to ${to}: ${subject}\n\n${body}"; say "sendmail to ${to}: ${subject}\n\n${body}";
return 1; return 1;

View file

@ -23,7 +23,7 @@
<nav class="deep-purple"> <nav class="deep-purple">
<div class="nav-wrapper container"> <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"> <ul id="nav-mobile" class="right">
% if (is_user_authenticated()) { % if (is_user_authenticated()) {
<li class="<%= navbar_class('/history') %>"><a href='/history' title="History"><i class="material-icons">history</i></a></li> <li class="<%= navbar_class('/history') %>"><a href='/history' title="History"><i class="material-icons">history</i></a></li>