Aupajo / almanack

Aggregate iCal and Google Calendar events. Pluggable or standalone app. UI optional and 100% customisable.
MIT License
54 stars 25 forks source link

Is there security? #22

Closed DerekFroese closed 5 years ago

DerekFroese commented 6 years ago

This looks like it might solve a problem I've had for a few months!

Is there any way to require a Pre-Shared Key to open the web page or ical feed?

I'd like to aggregate all my google calendars into one for sharing to specific people to open in their GCal, but not open it to the world.

steveb85 commented 5 years ago

i'm interested in this as well.

Aupajo commented 5 years ago

@DerekFroese @steveb85 Yes! There's several options, depending on what you want to achieve:

  1. An obfuscated URL (i.e. a pre-shared key in a URL), so you can have the feed at /my-shared-key/events.ics
  2. HTTP Basic auth, with a username/password
  3. OAuth (with a bit of work)

What kind of solution were you after?

DerekFroese commented 5 years ago

Personally, I like the obfuscated URL. It will have maximal compatibility, as many consumers of ical feeds are not able to do HTTP Basic Auth much less OAuth.

i.e., you wouldn't be able to add options 2 or 3 to Google Calendar, but you could add option 1.

Aupajo commented 5 years ago

@DerekFroese I think both obfuscated URL and basic auth will work with Google Calendar.

Obfuscated URL

For the obfuscated URL, find the following line in your config.ru:

run Almanack::Server

Change it to:

SECRET_TOKEN = 'shhhh'

app = Rack::Builder.app do
  map("/#{SECRET_TOKEN}") do
    run Almanack::Server
  end
end

run app

This will mount the calendar (and its feed) under /shhhh. If you want to avoid keeping the secret in your codebase (a good idea), I recommend using an environment variable:

SECRET_TOKEN = ENV.fetch('SECRET_TOKEN') { fail "Couldn't find a SECRET_TOKEN env var" } 

Environment variables are available on any unix-y system. On Heroku, you can set this with:

heroku config:set SECRET_TOKEN=shhhh

Warning: If you're using the default theme, you'll need to override layout.erb to fix the paths to the stylesheet and JavaScript. (I'll fix this in a future release).

Basic Auth

I believe most calendar apps, including Google Calendar, support basic auth, through use of the optional username and password parts of a URL, i.e. https://username:password@my.site/calendar.ics.

To use Basic Auth, find the following line in your config.ru:

run Almanack::Server

and change it to the following:

USERNAME = 'calendar'
PASSWORD = 'sshhhsecret'

use Rack::Auth::Basic, "My Calendar" do |given_username, given_password|
  Rack::Utils.secure_compare(PASSWORD, given_password) && given_username == USERNAME
end

run Almanack::Server

This will protect the application using HTTP Basic Auth. Please serve this over SSL/TLS (i.e. HTTPS) to prevent the password being sent in the clear.

If you want to avoid keeping the secret in your codebase (a good idea), I recommend using an environment variable:

CREDENTIALS = ENV.fetch('CREDENTIALS') { fail "Couldn't find a CREDENTIALS env var" } 
USERNAME, PASSWORD = credentials.split(':')

This assumes an environment variable called CREDENTIALS in the format username:password.

Environment variables are available on any system. On Heroku, you can set this with:

heroku config:set CREDENTIALS=username:password

Hope that helps!

Aupajo commented 5 years ago

Hi @DerekFroese. Did this solve your issue? Can I close this issue?

DerekFroese commented 5 years ago

HI Pete,

Yes, the configurations you listed solve the issue. Thanks!

On Fri, 10 May 2019 at 13:40, Pete Nicholls notifications@github.com wrote:

Hi @DerekFroese https://github.com/DerekFroese. Did this solve your issue? Can I close this issue?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Aupajo/almanack/issues/22#issuecomment-491423422, or mute the thread https://github.com/notifications/unsubscribe-auth/AAD3MBVSLRRODE2JF4ECYWLPUXMSNANCNFSM4FAC2ZRA .

-- Cheers,

Derek Froese

Aupajo commented 5 years ago

Great!

DerekFroese commented 5 years ago

I found that all of these changes were overwritten when Heroku is reloaded. Is it possible to have the secret token implemented as a Config Var so it can persist?

Aupajo commented 5 years ago

Sorry to hear that, @DerekFroese. Can you elaborate? Changes should be made via git and pushed to the Heroku repo to persist between deploys. The above example demonstrates how to do this with a Heroku config environment variable.

DerekFroese commented 5 years ago

Hi Aupajo,

If I understand correctly; I'd have to fork your repo and make my own in order to make changes to the code that persist across Heroku reboots and such. The problem for me is that my repo will become out-of-sync with your repo and will be an older version. I'm not sure I have the experience to keep my repo in sync with yours to have the latest version.

For my personal needs, it would be nice if the official code allowed for a config variable (set in Heroku) of an authentication token that would, if used, be required in the URL to access the calendar. But I also recognize most others may not need this and it's not fair of me to ask you to write code just for me :).

I apologize for my unfamiliarity; I have some small experience with PHP and web hosting, but Heroku is foreign to me.

Aupajo commented 5 years ago

Hi @DerekFroese. No you don't need to maintain a fork of this repo.

From scratch

The installation steps are:

gem install almanack
alamanack new my-custom-calender

This will create a directory called my-custom-calendar, which is small Git repo containing a Gemfile that keeps you in sync with releases of this project, and a configuration file you can customise your Almanack set-up. When you run:

almanack deploy

It will create or update a Heroku app for you.

From an app deployed with the Heroku button

If you deployed using the “Heroku Deploy” button, then the above steps were already performed for you. You can clone your existing Heroku git repository by logging in to Heroku, clicking on “Settings” and finding your “Heroku Git URL”:

image

You can clone the Heroku repo locally:

git clone https://git.heroku.com/my-almanack-app.git

Make the changes to config.ru, and then commit push them back:

git add config.ru -m "Add authentication"
git push origin master