raddar 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +3 -0
  4. data/Rakefile +27 -0
  5. data/app/assets/images/raddar/fallback/avatar/medium.png +0 -0
  6. data/app/assets/images/raddar/fallback/avatar/thumb.png +0 -0
  7. data/app/assets/javascripts/raddar/admin/dashboard.js.coffee +3 -0
  8. data/app/assets/javascripts/raddar/application.js +16 -0
  9. data/app/assets/javascripts/raddar/followerships.js.coffee +3 -0
  10. data/app/assets/javascripts/raddar/home.js.coffee +3 -0
  11. data/app/assets/javascripts/raddar/notifications.js.coffee +16 -0
  12. data/app/assets/javascripts/raddar/users.js.coffee +3 -0
  13. data/app/assets/javascripts/raddar/users/privacies.js.coffee +3 -0
  14. data/app/assets/stylesheets/raddar/admin/dashboard.css.scss +3 -0
  15. data/app/assets/stylesheets/raddar/application.css +14 -0
  16. data/app/assets/stylesheets/raddar/followerships.css.scss +3 -0
  17. data/app/assets/stylesheets/raddar/home.css.scss +3 -0
  18. data/app/assets/stylesheets/raddar/notifications.css.scss +6 -0
  19. data/app/assets/stylesheets/raddar/users.css.scss +3 -0
  20. data/app/assets/stylesheets/raddar/users/privacies.css.scss +3 -0
  21. data/app/controllers/raddar/admin/dashboard_controller.rb +11 -0
  22. data/app/controllers/raddar/admin/users_controller.rb +34 -0
  23. data/app/controllers/raddar/application_controller.rb +17 -0
  24. data/app/controllers/raddar/followerships_controller.rb +60 -0
  25. data/app/controllers/raddar/home_controller.rb +8 -0
  26. data/app/controllers/raddar/notifications_controller.rb +31 -0
  27. data/app/controllers/raddar/users/email_preferences_controller.rb +24 -0
  28. data/app/controllers/raddar/users/external_accounts_controller.rb +18 -0
  29. data/app/controllers/raddar/users/omniauth_callbacks_controller.rb +30 -0
  30. data/app/controllers/raddar/users/passwords_controller.rb +22 -0
  31. data/app/controllers/raddar/users/privacies_controller.rb +25 -0
  32. data/app/controllers/raddar/users/registrations_controller.rb +51 -0
  33. data/app/controllers/raddar/users/sessions_controller.rb +11 -0
  34. data/app/controllers/raddar/users_controller.rb +8 -0
  35. data/app/helpers/raddar/admin/dashboard_helper.rb +4 -0
  36. data/app/helpers/raddar/application_helper.rb +4 -0
  37. data/app/helpers/raddar/notifications_helper.rb +19 -0
  38. data/app/helpers/raddar/users/privacies_helper.rb +4 -0
  39. data/app/mailers/raddar/notification_mailer.rb +16 -0
  40. data/app/models/raddar/external_account.rb +12 -0
  41. data/app/models/raddar/followership.rb +20 -0
  42. data/app/models/raddar/followership_completion.rb +37 -0
  43. data/app/models/raddar/notification.rb +10 -0
  44. data/app/models/raddar/omniauth_completion.rb +83 -0
  45. data/app/models/raddar/role.rb +7 -0
  46. data/app/models/raddar/user.rb +70 -0
  47. data/app/policies/raddar/admin/dashboard_policy.rb +7 -0
  48. data/app/policies/raddar/admin/user_policy.rb +15 -0
  49. data/app/policies/raddar/application_policy.rb +42 -0
  50. data/app/policies/raddar/followership_policy.rb +25 -0
  51. data/app/policies/raddar/notification_policy.rb +21 -0
  52. data/app/policies/raddar/user_policy.rb +17 -0
  53. data/app/uploaders/raddar/avatar_uploader.rb +56 -0
  54. data/app/views/layouts/raddar/_alerts.html.erb +3 -0
  55. data/app/views/layouts/raddar/_navbar.html.erb +22 -0
  56. data/app/views/layouts/raddar/_notifications.html.erb +20 -0
  57. data/app/views/layouts/raddar/_user_menu.html.erb +21 -0
  58. data/app/views/layouts/raddar/application.html.erb +21 -0
  59. data/app/views/layouts/raddar/notification_mailer.html.erb +12 -0
  60. data/app/views/raddar/admin/dashboard/index.html.erb +6 -0
  61. data/app/views/raddar/admin/users/index.html.erb +11 -0
  62. data/app/views/raddar/admin/users/show.html.erb +12 -0
  63. data/app/views/raddar/followerships/followers.html.erb +9 -0
  64. data/app/views/raddar/followerships/following.html.erb +9 -0
  65. data/app/views/raddar/home/index.html.erb +1 -0
  66. data/app/views/raddar/notification_mailer/new_follower.html.erb +11 -0
  67. data/app/views/raddar/notifications/index.html.erb +12 -0
  68. data/app/views/raddar/notifications/index.json.jbuilder +4 -0
  69. data/app/views/raddar/users/confirmations/new.html.erb +16 -0
  70. data/app/views/raddar/users/email_preferences/edit.html.erb +11 -0
  71. data/app/views/raddar/users/external_accounts/index.html.erb +14 -0
  72. data/app/views/raddar/users/mailer/confirmation_instructions.html.erb +5 -0
  73. data/app/views/raddar/users/mailer/reset_password_instructions.html.erb +8 -0
  74. data/app/views/raddar/users/mailer/unlock_instructions.html.erb +7 -0
  75. data/app/views/raddar/users/passwords/change.html.erb +13 -0
  76. data/app/views/raddar/users/passwords/edit.html.erb +19 -0
  77. data/app/views/raddar/users/passwords/new.html.erb +15 -0
  78. data/app/views/raddar/users/privacies/edit.html.erb +12 -0
  79. data/app/views/raddar/users/registrations/destroy.html.erb +13 -0
  80. data/app/views/raddar/users/registrations/edit.html.erb +30 -0
  81. data/app/views/raddar/users/registrations/new.html.erb +16 -0
  82. data/app/views/raddar/users/sessions/new.html.erb +13 -0
  83. data/app/views/raddar/users/shared/_links.erb +25 -0
  84. data/app/views/raddar/users/show.html.erb +52 -0
  85. data/app/views/raddar/users/unlocks/new.html.erb +16 -0
  86. data/config/cucumber.yml +8 -0
  87. data/config/initializers/carrierwave.rb +10 -0
  88. data/config/initializers/devise.rb +262 -0
  89. data/config/initializers/kaminari_config.rb +10 -0
  90. data/config/initializers/simple_form.rb +142 -0
  91. data/config/initializers/simple_form_bootstrap.rb +17 -0
  92. data/config/locales/devise.en.yml +59 -0
  93. data/config/locales/en.yml +49 -0
  94. data/config/locales/flash.en.yml +20 -0
  95. data/config/locales/mailers.en.yml +5 -0
  96. data/config/locales/simple_form.en.yml +35 -0
  97. data/config/locales/views.en.yml +36 -0
  98. data/config/routes.rb +43 -0
  99. data/db/migrate/20130824222728_devise_create_raddar_users.rb +66 -0
  100. data/db/migrate/20131013222926_create_raddar_followerships.rb +14 -0
  101. data/db/migrate/20131020174318_create_raddar_roles.rb +11 -0
  102. data/db/migrate/20131020175354_create_join_table_raddar_role_user.rb +8 -0
  103. data/db/migrate/20131021134623_create_raddar_notifications.rb +13 -0
  104. data/db/migrate/20131026133924_create_raddar_external_accounts.rb +23 -0
  105. data/lib/raddar.rb +15 -0
  106. data/lib/raddar/engine.rb +5 -0
  107. data/lib/raddar/hstore_serializer.rb +22 -0
  108. data/lib/raddar/version.rb +3 -0
  109. data/lib/tasks/cucumber.rake +65 -0
  110. data/lib/tasks/raddar_tasks.rake +4 -0
  111. metadata +390 -0
@@ -0,0 +1,25 @@
1
+ module Raddar
2
+ class FollowershipPolicy < ApplicationPolicy
3
+ class Scope < Struct.new(:user, :scope)
4
+ def resolve
5
+ scope
6
+ end
7
+ end
8
+
9
+ def create?
10
+ @user.present?
11
+ end
12
+
13
+ def destroy?
14
+ @user.present?
15
+ end
16
+
17
+ def followers?
18
+ @user.present?
19
+ end
20
+
21
+ def following?
22
+ @user.present?
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module Raddar
2
+ class NotificationPolicy < ApplicationPolicy
3
+ class Scope < Struct.new(:user, :scope)
4
+ def resolve
5
+ scope
6
+ end
7
+ end
8
+
9
+ def index?
10
+ @user.present?
11
+ end
12
+
13
+ def show?
14
+ @user.present? && @record.user == @user
15
+ end
16
+
17
+ def read_all?
18
+ @user.present?
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module Raddar
2
+ class UserPolicy < ApplicationPolicy
3
+ class Scope < Struct.new(:user, :scope)
4
+ def resolve
5
+ scope
6
+ end
7
+ end
8
+
9
+ def show?
10
+ @user.present?
11
+ end
12
+
13
+ def read_field?(field)
14
+ ((@record.privacy || {})[field] != 'only_me') || (@user == @record)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,56 @@
1
+ module Raddar
2
+ class AvatarUploader < CarrierWave::Uploader::Base
3
+
4
+ # Include RMagick or MiniMagick support:
5
+ # include CarrierWave::RMagick
6
+ include CarrierWave::MiniMagick
7
+
8
+ # Override the directory where uploaded files will be stored.
9
+ # This is a sensible default for uploaders that are meant to be mounted:
10
+ def store_dir
11
+ "uploads/#{model.class.to_s.underscore}/#{model.id}/#{mounted_as}"
12
+ end
13
+
14
+ # Provide a default URL as a default if there hasn't been a file uploaded:
15
+ # def default_url
16
+ # # For Rails 3.1+ asset pipeline compatibility:
17
+ # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
18
+ #
19
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
20
+ # end
21
+ def default_url
22
+ ActionController::Base.helpers.asset_path("fallback/avatar/#{ version_name }.png")
23
+ end
24
+
25
+ # Process files as they are uploaded:
26
+ # process :scale => [200, 300]
27
+ #
28
+ # def scale(width, height)
29
+ # # do something
30
+ # end
31
+
32
+ # Create different versions of your uploaded files:
33
+
34
+ process resize_to_limit: [760, 1160]
35
+
36
+ version :medium do
37
+ process resize_to_fill: [360, 360]
38
+ end
39
+
40
+ version :thumb do
41
+ process resize_to_fill: [60, 60]
42
+ end
43
+
44
+ # Add a white list of extensions which are allowed to be uploaded.
45
+ # For images you might use something like this:
46
+ def extension_white_list
47
+ %w(jpg jpeg gif png)
48
+ end
49
+
50
+ # Override the filename of the uploaded files:
51
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
52
+ # def filename
53
+ # "something.jpg" if original_filename
54
+ # end
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ <% flash.each do |type, msg| %>
2
+ <%= content_tag :div, msg, class: "alert alert-#{ type.to_s == 'alert' ? 'danger' : 'info' }" %>
3
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <header class="navbar navbar-default navbar-static-top" role="navigation">
2
+ <div class='container'>
3
+ <div class="navbar-header">
4
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
5
+ <span class="sr-only">Toggle navigation</span>
6
+ <span class="icon-bar"></span>
7
+ <span class="icon-bar"></span>
8
+ <span class="icon-bar"></span>
9
+ </button>
10
+
11
+ <%= link_to Raddar.app_name, raddar.root_path, class: 'navbar-brand' %>
12
+ </div>
13
+
14
+ <div class="collapse navbar-collapse navbar-ex1-collapse">
15
+ <ul class="nav navbar-nav navbar-right">
16
+ <%= render 'layouts/raddar/notifications' %>
17
+
18
+ <%= render 'layouts/raddar/user_menu' %>
19
+ </ul>
20
+ </div>
21
+ </div>
22
+ </header>
@@ -0,0 +1,20 @@
1
+ <% if user_signed_in? %>
2
+ <li class="dropdown">
3
+ <%= link_to raddar.notifications_path, id: 'notifications-menu', class: 'dropdown-toggle', data: { toggle: 'dropdown' } do %>
4
+ <span class="glyphicon glyphicon-flag"></span>
5
+
6
+ <% if unread_notifications_count(current_user) > 0 %>
7
+ <span class="badge"><%= unread_notifications_count(current_user) %></span>
8
+ <% end %>
9
+ <% end %>
10
+
11
+ <ul class="dropdown-menu">
12
+ <% last_notifications(current_user).each do |notification| %>
13
+ <li><%= link_to_notification notification %></li>
14
+ <li class="divider"></li>
15
+ <% end %>
16
+
17
+ <li><%= link_to t('notifications.see_all'), raddar.notifications_path %></li>
18
+ </ul>
19
+ </li>
20
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <% if user_signed_in? %>
2
+ <li class="dropdown">
3
+ <%= link_to [raddar, current_user], id: 'user-menu', class: 'dropdown-toggle', data: { toggle: 'dropdown' } do %>
4
+ <%= current_user.name %>
5
+ <b class="caret"></b>
6
+ <% end %>
7
+
8
+ <ul class="dropdown-menu">
9
+ <li><%= link_to t('user.show'), [raddar, current_user] %></li>
10
+ <li><%= link_to t('user.registration.edit'), raddar.edit_user_registration_path %></li>
11
+ <li class="divider"></li>
12
+ <% if current_user.admin? %>
13
+ <li><%= link_to t('admin.dashboard'), raddar.admin_root_path %></li>
14
+ <li class="divider"></li>
15
+ <% end %>
16
+ <li><%= link_to t('user.session.destroy'), raddar.destroy_user_session_path, method: :delete %></li>
17
+ </ul>
18
+ </li>
19
+ <% else %>
20
+ <li><%= link_to t('user.session.new'), raddar.new_user_session_path %></li>
21
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= Raddar.app_name %></title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <%= stylesheet_link_tag 'application', media: 'all' %>
7
+
8
+ <%= csrf_meta_tags %>
9
+ </head>
10
+ <body>
11
+ <%= render 'layouts/raddar/navbar' %>
12
+
13
+ <div class='container' id='main-container'>
14
+ <%= render 'layouts/raddar/alerts' %>
15
+
16
+ <%= yield %>
17
+ </div>
18
+
19
+ <%= javascript_include_tag 'application' %>
20
+ </body>
21
+ </html>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
5
+ </head>
6
+
7
+ <body style="background-color: #eee; margin: 0; padding: 20px; font-family: Helvetica, Arial, sans-serif">
8
+ <div style="background-color: #fff; margin: 0 auto; padding: 20px">
9
+ <%= yield %>
10
+ </div>
11
+ </body>
12
+ </html>
@@ -0,0 +1,6 @@
1
+ <div class='page-header'>
2
+ <h1><%= t 'admin.dashboard' %></h1>
3
+ </div>
4
+
5
+
6
+ <%= link_to t('admin.users'), admin_users_path %>
@@ -0,0 +1,11 @@
1
+ <div class="page-header">
2
+ <h1><%= t 'admin.users' %></h1>
3
+ </div>
4
+
5
+ <ul>
6
+ <% @users.each do |user| %>
7
+ <li class="user"><%= link_to user.name, admin_user_path(user) %></li>
8
+ <% end %>
9
+ </ul>
10
+
11
+ <%= paginate @users %>
@@ -0,0 +1,12 @@
1
+ <div class="page-header">
2
+ <h1><%= @user.name %></h1>
3
+ </div>
4
+
5
+ <%= simple_form_for([:admin, @user]) do |f| %>
6
+ <%= f.input :state, collection: [:active, :blocked], as: :radio_buttons %>
7
+
8
+ <%= f.association :roles, as: :check_boxes,
9
+ label_method: ->(r) { t(r.name, scope: 'role.names') } %>
10
+
11
+ <%= f.submit t(:save), class: 'btn btn-default' %>
12
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <div class='page-header'>
2
+ <h1><%= t 'followership.followers' %></h1>
3
+ </div>
4
+
5
+ <ul>
6
+ <% @followable.followers.each do |followership| %>
7
+ <li><%= link_to followership.user.name, followership.user %></li>
8
+ <% end %>
9
+ </ul>
@@ -0,0 +1,9 @@
1
+ <div class='page-header'>
2
+ <h1><%= t 'followership.following' %></h1>
3
+ </div>
4
+
5
+ <ul>
6
+ <% @user.followerships.each do |followership| %>
7
+ <li><%= link_to followership.followable.name, followership.followable %></li>
8
+ <% end %>
9
+ </ul>
@@ -0,0 +1 @@
1
+ <h1><%= Raddar.app_name %></h1>
@@ -0,0 +1,11 @@
1
+ <h1>Hi, <%= @user.name %>!</h1>
2
+
3
+ <p>
4
+ <%= link_to @follower.name, raddar.notification_url(@notification) %>
5
+ is now following you!
6
+ </p>
7
+
8
+ <p>
9
+ To follow back, please go to <%= @follower.name %>'s profile by
10
+ <%= link_to 'clicking here', raddar.notification_url(@notification) %>.
11
+ </p>
@@ -0,0 +1,12 @@
1
+ <div class="page-title">
2
+ <h1><%= t '.title' %></h1>
3
+ </div>
4
+
5
+
6
+ <ul>
7
+ <% @notifications.each do |notification| %>
8
+ <li><%= link_to_notification notification %></li>
9
+ <% end %>
10
+ </ul>
11
+
12
+ <%= paginate @notifications %>
@@ -0,0 +1,4 @@
1
+ json.array!(@notifications) do |notification|
2
+ json.extract! notification, :content, :item_path, :read, :user_id, :notifiable_id
3
+ json.url notification_url(notification, format: :json)
4
+ end
@@ -0,0 +1,16 @@
1
+ <h2>Resend confirmation instructions</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+ <%= f.full_error :confirmation_token %>
6
+
7
+ <div class="form-inputs">
8
+ <%= f.input :email, :required => true, :autofocus => true %>
9
+ </div>
10
+
11
+ <div class="form-actions">
12
+ <%= f.button :submit, "Resend confirmation instructions" %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <%= render "users/shared/links" %>
@@ -0,0 +1,11 @@
1
+ <h1><%= t '.title' %></h1>
2
+
3
+ <%= simple_form_for(@user, url: user_email_preferences_path, method: :patch) do |f| %>
4
+ <%= f.simple_fields_for(:email_preferences) do |p| %>
5
+ <% Raddar::User.email_preferences_keys.each do |key| %>
6
+ <%= p.input key, as: :boolean, label: false, inline_label: t(".keys.#{ key }"), input_html: { checked: @user.email_preferences[key] } %>
7
+ <% end %>
8
+ <% end %>
9
+
10
+ <%= f.button :submit, t('.submit') %>
11
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <h1><%= t '.title' %></h1>
2
+
3
+ <% Raddar::User.omniauth_providers.each do |provider| %>
4
+ <div class="external-account <%= provider %>">
5
+ <h1><%= provider.to_s.titleize %></h1>
6
+
7
+ <% if account = @user.external_accounts.find_by(provider: provider) %>
8
+ <%= link_to "@#{account.name}", account.url, target: '_blank' %>
9
+ <%= link_to t('.destroy', provider: provider.to_s.titleize), [:user, account], method: :delete, class: 'btn btn-default' %>
10
+ <% else %>
11
+ <%= link_to t('.connect', provider: provider.to_s.titleize), user_omniauth_authorize_path(provider), class: 'btn btn-primary' %>
12
+ <% end %>
13
+ </div>
14
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <p>Welcome <%= @email %>!</p>
2
+
3
+ <p>You can confirm your account email through the link below:</p>
4
+
5
+ <p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
@@ -0,0 +1,8 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Someone has requested a link to change your password. You can do this through the link below.</p>
4
+
5
+ <p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %></p>
6
+
7
+ <p>If you didn't request this, please ignore this email.</p>
8
+ <p>Your password won't change until you access the link above and create a new one.</p>
@@ -0,0 +1,7 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
4
+
5
+ <p>Click the link below to unlock your account:</p>
6
+
7
+ <p><%= link_to 'Unlock my account', user_unlock_url(@resource, :unlock_token => @token) %></p>
@@ -0,0 +1,13 @@
1
+ <h1><%= t '.title' %></h1>
2
+
3
+ <%= simple_form_for(@user, url: raddar.do_change_user_password_path) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <%= f.input :current_password, autocomplete: 'off', required: true, input_html: { class: 'form-control'} %>
7
+ <%= f.input :password, label: t('.password_label'), autocomplete: 'off', required: true, input_html: { class: 'form-control'} %>
8
+ <%= f.input :password_confirmation, autocomplete: 'off', required: true, input_html: { class: 'form-control'} %>
9
+
10
+ <div class="form-group">
11
+ <%= f.button :submit, t('.submit') %>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <h2>Change your password</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <%= f.input :reset_password_token, :as => :hidden %>
7
+ <%= f.full_error :reset_password_token %>
8
+
9
+ <div class="form-inputs">
10
+ <%= f.input :password, :label => "New password", :required => true, :autofocus => true %>
11
+ <%= f.input :password_confirmation, :label => "Confirm your new password", :required => true %>
12
+ </div>
13
+
14
+ <div class="form-actions">
15
+ <%= f.button :submit, "Change my password" %>
16
+ </div>
17
+ <% end %>
18
+
19
+ <%= render "raddar/users/shared/links" %>
@@ -0,0 +1,15 @@
1
+ <h2>Forgot your password?</h2>
2
+
3
+ <%= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="form-inputs">
7
+ <%= f.input :email, :required => true, :autofocus => true %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit, "Send me reset password instructions" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render "raddar/users/shared/links" %>