Skip to content
This repository has been archived by the owner on Dec 8, 2017. It is now read-only.

Add guest user capability #3

Merged
merged 10 commits into from
Dec 14, 2014
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ private_data_path: _data/private
# team member images
team_img_dir: assets/images/team
missing_team_member_img: logo-18f.jpg
guest_user_img: logo-18f.jpg
2 changes: 1 addition & 1 deletion _data/private
4 changes: 2 additions & 2 deletions _layouts/bare.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<section class="container bare">

<!--# include virtual="{{ site.baseurl }}/auth/$REMOTE_USER/index.html" -->
{% unless site.public %}
<!--# include virtual="{{ site.baseurl }}/auth/$REMOTE_USER/index.html" -->{% endunless %}

<div class="bare-logo" role="banner" itemscope itemtype="http://schema.org/WPHeader">
<a href="{{ site.baseurl }}/">
Expand Down
4 changes: 4 additions & 0 deletions _layouts/guest_user_auth_include.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="auth-include">
<span>{{ page.user.full_name }}</span>
<img src="{{ site.baseurl }}/{{ site.team_img_dir }}/{{ site.guest_user_img }}">
</div>
6 changes: 3 additions & 3 deletions _layouts/team_member_auth_include.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="team-member-auth-include">
<a href="{{ site.baseurl }}/team/{{ page.member.name }}"><span>{{ page.member.full_name }}</span>
<img class="team-member-thumb" src="{{ site.baseurl }}/{{ page.member.image }}"></a>
<div class="auth-include">
<a href="{{ site.baseurl }}/team/{{ page.user.name }}"><span>{{ page.user.full_name }}</span>
<img src="{{ site.baseurl }}/{{ page.user.image }}"></a>
</div>
40 changes: 28 additions & 12 deletions _plugins/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,51 @@ class Auth
# true.
# +site+:: Jekyll site object
def self.generate_artifacts(site)
return if site.config['public']
return if site.config['public'] == true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ruby convention is rely on truthiness, unless there's some reason to explicitly check for the boolean value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know why I did that. Fixed.

team = site.data['team'].values.select {|i| i.member? 'email'}
return if team.empty?
team.each {|i| generate_team_authentication_include(site, i)}
generate_hub_authenticated_emails(site, team)
guests = site.data['guest_users'] || []
return if team.empty? and guests.empty?

groups = {
team => 'team_member_auth_include.html',
guests => 'guest_user_auth_include.html',
}

groups.each do |group, layout|
group.each do |user|
generate_user_authentication_include(site, user, layout)
end
end

generate_hub_authenticated_emails(site, team, guests)
end

private

# Generates the upper-right-corner divs used to identify the authenticated
# user. The divs are imported via a Server Side Include directive in
# _layouts/bare.html.
# +site+:: Jekyll site object
# +member+:: team member hash
def self.generate_team_authentication_include(site, member)
username = member['email'].sub(/@.+$/, '')
# +user+:: user hash
def self.generate_user_authentication_include(site, user, layout)
username = user['email'].sub(/@.+$/, '')
page = Page.new(site, File.join('auth', username), 'index.html',
'team_member_auth_include.html',
"#{member['full_name']} Authentication Include")
page.data['member'] = member
layout, "#{user['full_name']} Authentication Include")
page.data['user'] = user
site.pages << page
end

# Generates the list of email addresses permitted to access the Hub after
# passing through the google_auth_proxy. See deploy/README.md for details.
# +site+:: Jekyll site object
# +team+:: array of team member hashes
def self.generate_hub_authenticated_emails(site, team)
# +guests+ array of guest user hashes
def self.generate_hub_authenticated_emails(site, team, guests)
page = Page.new(site, 'auth', 'hub-authenticated-emails.txt',
'hub-authenticated-emails.txt', 'Authenticated Emails')
page.data['addrs'] = team.map {|i| i['email']}.sort!
page.data['addrs'] = team.map {|i| i['email']}
page.data['addrs'].concat(guests.map {|i| i['email']})
page.data['addrs'].sort!
site.pages << page
end
end
Expand Down
11 changes: 11 additions & 0 deletions _plugins/joiner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def self.join_data(site)

impl.join_snippet_data
impl.join_project_status
impl.import_guest_users
impl.filter_private_pages

site.data.delete 'public'
Expand Down Expand Up @@ -283,6 +284,16 @@ def join_project_status
@data['private'].delete 'project_status'
end

# Imports the guest_users list into the top-level site.data object.
def import_guest_users
private_data = site.data['private'] || {}
hub_data = private_data['hub'] || {}
if hub_data.member? 'guest_users'
site.data['guest_users'] = site.data['private']['hub']['guest_users']
site.data['private']['hub'].delete 'guest_users'
end
end

# Filters out private pages when generating the public Hub.
def filter_private_pages
if @public_mode
Expand Down
104 changes: 104 additions & 0 deletions _test/auth_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
require_relative "../_plugins/auth"
require_relative "page"

require "jekyll"
require "jekyll/site"
require "minitest/autorun"

module Hub
class AuthTest < ::Minitest::Test
def setup
@site = ::Jekyll::Site.new ::Jekyll::Configuration::DEFAULTS

@team = {
'mbland' => {
'email' => 'michael.bland@gsa.gov',
'full_name' => 'Mike Bland'},
'foobar' => {
'email' => 'foo.bar@notgsa.gov',
'full_name' => 'Foo Bar'},
}

@guests = [
{'email' => 'mbland@acm.org',
'full_name' => 'Mike Bland'},
{'email' => 'baz.quux@notgsa.gov',
'full_name' => 'Baz Quux'},
]
end

def actual_auth_include_users
unless @site.pages.empty?
@site.pages[0..-2].map {|page| page['user']}
else
[]
end
end

def actual_auth_emails
unless @site.pages.empty?
@site.pages.last['addrs']
else
[]
end
end

def test_empty_team_and_guests
@site.data['team'] = {}
@site.data['guest_users'] = []
Auth.generate_artifacts @site

assert_empty actual_auth_include_users
assert_empty actual_auth_emails
end

def test_no_artifacts_in_public_mode
@site.data['team'] = @team
@site.data['guest_users'] = @guests
@site.config['public'] = true
Auth.generate_artifacts @site

assert_empty actual_auth_include_users
assert_empty actual_auth_emails
end

def test_team_artifacts_generated
@site.data['team'] = @team
Auth.generate_artifacts @site

assert_equal(
[@team['mbland'], @team['foobar']],
actual_auth_include_users)
assert_equal(
['foo.bar@notgsa.gov', 'michael.bland@gsa.gov'],
actual_auth_emails)
end

def test_guest_artifacts_generated
@site.data['team'] = {}
@site.data['guest_users'] = @guests
Auth.generate_artifacts @site

assert_equal(
[@guests[0], @guests[1]],
actual_auth_include_users)
assert_equal(
['baz.quux@notgsa.gov', 'mbland@acm.org'],
actual_auth_emails)
end

def test_team_and_guest_artifacts_generated
@site.data['team'] = @team
@site.data['guest_users'] = @guests
Auth.generate_artifacts @site

assert_equal(
[@team['mbland'], @team['foobar'], @guests[0], @guests[1]],
actual_auth_include_users)
assert_equal(
['baz.quux@notgsa.gov', 'foo.bar@notgsa.gov',
'mbland@acm.org', 'michael.bland@gsa.gov'],
actual_auth_emails)
end
end
end
45 changes: 35 additions & 10 deletions _test/joiner_test.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
require_relative "../_plugins/joiner"
require_relative "page"

require "jekyll"
require "jekyll/page"
require "jekyll/site"
require_relative "../_plugins/joiner"
require "test/unit"
require "minitest/autorun"

module Hub
class DummyTestPage < ::Jekyll::Page
def initialize(site, dir, filename)
@site = site
@base = 'fake_test_basedir'
@dir = dir
@name = filename
class ImportGuestUsers < ::Minitest::Test
def setup
@site = ::Jekyll::Site.new ::Jekyll::Configuration::DEFAULTS
end

def test_no_private_data
assert_nil JoinerImpl.new(@site).import_guest_users
end

def test_no_hub_data
@site.data['private'] = {}
assert_nil JoinerImpl.new(@site).import_guest_users
assert_nil @site.data['guest_users']
end

def test_no_guest_users
@site.data['private'] = {'hub' => {}}
assert_nil JoinerImpl.new(@site).import_guest_users
assert_nil @site.data['guest_users']
end

def test_guest_users_moved_to_top_level
guests = [
{'email' => 'michael.bland@gsa.gov',
'full_name' => 'Mike Bland'},
]
@site.data['private'] = {'hub' => {'guest_users' => guests}}
assert_equal guests, JoinerImpl.new(@site).import_guest_users
assert_equal guests, @site.data['guest_users']
assert_nil @site.data['private']['hub']['guest_users']
end
end

class TestFilterPrivatePages < ::Test::Unit::TestCase
class FilterPrivatePagesTest < ::Minitest::Test
def setup
@site = ::Jekyll::Site.new ::Jekyll::Configuration::DEFAULTS
@all_page_names = []
Expand Down
13 changes: 13 additions & 0 deletions _test/page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "jekyll"
require "jekyll/page"

module Hub
class DummyTestPage < ::Jekyll::Page
def initialize(site, dir, filename)
@site = site
@base = 'fake_test_basedir'
@dir = dir
@name = filename
end
end
end
5 changes: 4 additions & 1 deletion assets/_sass/_hub.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
margin-right: 5px;
}

.team-member-auth-include {
.auth-include {
position: absolute;
top: 0;
right: 0;
Expand All @@ -86,5 +86,8 @@
}
img {
vertical-align: middle;
width: 50px;
height: auto;
margin-right: 5px;
}
}