outpost-cms 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +295 -0
- data/Rakefile +26 -0
- data/app/assets/images/glyphicons-halflings-red.png +0 -0
- data/app/assets/javascripts/outpost/application.js +1 -0
- data/app/assets/javascripts/outpost/auto_slug_field.js.coffee +53 -0
- data/app/assets/javascripts/outpost/base.js.coffee +1 -0
- data/app/assets/javascripts/outpost/date_time_input.js.coffee +108 -0
- data/app/assets/javascripts/outpost/field_counter.js.coffee +93 -0
- data/app/assets/javascripts/outpost/field_manager.js.coffee +37 -0
- data/app/assets/javascripts/outpost/global_plugins.js.coffee +87 -0
- data/app/assets/javascripts/outpost/index_manager.js.coffee +88 -0
- data/app/assets/javascripts/outpost/notification.js.coffee +46 -0
- data/app/assets/javascripts/outpost/preview.js.coffee +60 -0
- data/app/assets/javascripts/outpost/templates/date_field.jst.eco +3 -0
- data/app/assets/javascripts/outpost/templates/loading.jst.eco +11 -0
- data/app/assets/javascripts/outpost/templates/slug_generate_button.jst.eco +1 -0
- data/app/assets/javascripts/outpost/templates/time_field.jst.eco +3 -0
- data/app/assets/javascripts/outpost/templates.js +1 -0
- data/app/assets/javascripts/outpost.js +32 -0
- data/app/assets/stylesheets/outpost/_base.css.scss +127 -0
- data/app/assets/stylesheets/outpost/_edit.css.scss +13 -0
- data/app/assets/stylesheets/outpost/_forms.css.scss +116 -0
- data/app/assets/stylesheets/outpost/_index.css.scss +68 -0
- data/app/assets/stylesheets/outpost/_utility.css.scss +16 -0
- data/app/assets/stylesheets/outpost/application.css.scss +1 -0
- data/app/assets/stylesheets/outpost/bootstrap/bootstrap.css.scss +49 -0
- data/app/assets/stylesheets/outpost/bootstrap/datepicker.css.scss +301 -0
- data/app/assets/stylesheets/outpost.css.scss +14 -0
- data/app/controllers/outpost/application_controller.rb +40 -0
- data/app/controllers/outpost/base_controller.rb +3 -0
- data/app/controllers/outpost/errors_controller.rb +9 -0
- data/app/controllers/outpost/home_controller.rb +2 -0
- data/app/controllers/outpost/resource_controller.rb +12 -0
- data/app/controllers/outpost/sessions_controller.rb +36 -0
- data/app/helpers/authorization_helper.rb +44 -0
- data/app/helpers/list_helper.rb +243 -0
- data/app/helpers/outpost_helper.rb +49 -0
- data/app/helpers/render_helper.rb +41 -0
- data/app/helpers/utility_helper.rb +136 -0
- data/app/inputs/date_time_input.rb +12 -0
- data/app/models/permission.rb +18 -0
- data/app/models/user_permission.rb +4 -0
- data/app/views/kaminari/bootstrap/_first_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_gap.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_last_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_next_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_page.html.erb +3 -0
- data/app/views/kaminari/bootstrap/_paginator.html.erb +17 -0
- data/app/views/kaminari/bootstrap/_prev_page.html.erb +3 -0
- data/app/views/layouts/outpost/application.html.erb +101 -0
- data/app/views/layouts/outpost/minimal.html.erb +26 -0
- data/app/views/outpost/errors/error_404.html.erb +1 -0
- data/app/views/outpost/errors/error_500.html.erb +8 -0
- data/app/views/outpost/home/dashboard.html.erb +1 -0
- data/app/views/outpost/resource/_errors.html.erb +11 -0
- data/app/views/outpost/resource/_extra_fields.html.erb +1 -0
- data/app/views/outpost/resource/_form_fields.html.erb +9 -0
- data/app/views/outpost/resource/edit.html.erb +44 -0
- data/app/views/outpost/resource/index.html.erb +22 -0
- data/app/views/outpost/resource/new.html.erb +21 -0
- data/app/views/outpost/resource/search.html.erb +1 -0
- data/app/views/outpost/resource/show.html.erb +1 -0
- data/app/views/outpost/sessions/new.html.erb +16 -0
- data/app/views/outpost/shared/_add_link.html.erb +1 -0
- data/app/views/outpost/shared/_breadcrumbs.html.erb +15 -0
- data/app/views/outpost/shared/_cancel_link.html.erb +1 -0
- data/app/views/outpost/shared/_columns.html.erb +5 -0
- data/app/views/outpost/shared/_filters.html.erb +16 -0
- data/app/views/outpost/shared/_flash_messages.html.erb +6 -0
- data/app/views/outpost/shared/_form_block.html.erb +18 -0
- data/app/views/outpost/shared/_form_nav.html.erb +12 -0
- data/app/views/outpost/shared/_headers.html.erb +16 -0
- data/app/views/outpost/shared/_index_header.html.erb +4 -0
- data/app/views/outpost/shared/_list_table.html.erb +7 -0
- data/app/views/outpost/shared/_modal.html.erb +16 -0
- data/app/views/outpost/shared/_navigation.html.erb +31 -0
- data/app/views/outpost/shared/_notice.html.erb +1 -0
- data/app/views/outpost/shared/_pagination.html.erb +2 -0
- data/app/views/outpost/shared/_preview_errors.html.erb +9 -0
- data/app/views/outpost/shared/_submit_row.html.erb +50 -0
- data/config/routes.rb +4 -0
- data/lib/action_view/helpers/form_builder.rb +71 -0
- data/lib/outpost/breadcrumbs.rb +73 -0
- data/lib/outpost/config.rb +63 -0
- data/lib/outpost/controller/actions.rb +72 -0
- data/lib/outpost/controller/authentication.rb +34 -0
- data/lib/outpost/controller/authorization.rb +28 -0
- data/lib/outpost/controller/callbacks.rb +14 -0
- data/lib/outpost/controller/custom_errors.rb +41 -0
- data/lib/outpost/controller/filtering.rb +22 -0
- data/lib/outpost/controller/helpers.rb +52 -0
- data/lib/outpost/controller/ordering.rb +46 -0
- data/lib/outpost/controller/preferences.rb +71 -0
- data/lib/outpost/controller.rb +123 -0
- data/lib/outpost/engine.rb +10 -0
- data/lib/outpost/helpers/naming.rb +22 -0
- data/lib/outpost/helpers.rb +6 -0
- data/lib/outpost/hook.rb +35 -0
- data/lib/outpost/list/base.rb +78 -0
- data/lib/outpost/list/column.rb +24 -0
- data/lib/outpost/list/filter.rb +37 -0
- data/lib/outpost/list.rb +15 -0
- data/lib/outpost/model/authentication.rb +34 -0
- data/lib/outpost/model/authorization.rb +32 -0
- data/lib/outpost/model/identifier.rb +39 -0
- data/lib/outpost/model/methods.rb +23 -0
- data/lib/outpost/model/naming.rb +63 -0
- data/lib/outpost/model/routing.rb +138 -0
- data/lib/outpost/model/serializer.rb +27 -0
- data/lib/outpost/model.rb +22 -0
- data/lib/outpost/test.rb +21 -0
- data/lib/outpost/version.rb +3 -0
- data/lib/outpost-cms.rb +2 -0
- data/lib/outpost.rb +80 -0
- data/lib/tasks/outpost_tasks.rake +7 -0
- data/spec/controllers/authentication_spec.rb +62 -0
- data/spec/controllers/sessions_controller_spec.rb +99 -0
- data/spec/factories.rb +31 -0
- data/spec/helpers/authorization_helper_spec.rb +47 -0
- data/spec/helpers/list_helper_spec.rb +74 -0
- data/spec/helpers/outpost_helper_spec.rb +5 -0
- data/spec/helpers/render_helper_spec.rb +19 -0
- data/spec/helpers/utility_helper_spec.rb +53 -0
- data/spec/internal/app/controllers/application_controller.rb +3 -0
- data/spec/internal/app/controllers/outpost/people_controller.rb +23 -0
- data/spec/internal/app/controllers/outpost/pidgeons_controller.rb +5 -0
- data/spec/internal/app/controllers/people_controller.rb +9 -0
- data/spec/internal/app/controllers/pidgeons_controller.rb +3 -0
- data/spec/internal/app/models/person.rb +10 -0
- data/spec/internal/app/models/pidgeon.rb +3 -0
- data/spec/internal/app/models/post.rb +4 -0
- data/spec/internal/app/models/user.rb +4 -0
- data/spec/internal/app/views/people/index.html.erb +7 -0
- data/spec/internal/app/views/people/show.html.erb +1 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/initializers/configuration.rb +3 -0
- data/spec/internal/config/initializers/outpost.rb +6 -0
- data/spec/internal/config/routes.rb +16 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +44 -0
- data/spec/internal/db/seeds.rb +14 -0
- data/spec/internal/log/test.log +59277 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/breadcrumbs_spec.rb +54 -0
- data/spec/lib/config_spec.rb +76 -0
- data/spec/lib/controller/actions_spec.rb +5 -0
- data/spec/lib/controller/authorization_spec.rb +4 -0
- data/spec/lib/controller/callbacks_spec.rb +31 -0
- data/spec/lib/controller/helpers_spec.rb +33 -0
- data/spec/lib/controller_spec.rb +25 -0
- data/spec/lib/helpers/naming_spec.rb +10 -0
- data/spec/lib/hook_spec.rb +13 -0
- data/spec/lib/list/base_spec.rb +96 -0
- data/spec/lib/list/column_spec.rb +46 -0
- data/spec/lib/list/filter_spec.rb +44 -0
- data/spec/lib/model/authentication_spec.rb +29 -0
- data/spec/lib/model/authorization_spec.rb +66 -0
- data/spec/lib/model/identifier_spec.rb +51 -0
- data/spec/lib/model/methods_spec.rb +8 -0
- data/spec/lib/model/naming_spec.rb +55 -0
- data/spec/lib/model/routing_spec.rb +166 -0
- data/spec/lib/model/serializer_spec.rb +13 -0
- data/spec/lib/outpost_spec.rb +34 -0
- data/spec/models/permission_spec.rb +10 -0
- data/spec/models/user_permission_spec.rb +4 -0
- data/spec/spec_helper.rb +22 -0
- metadata +411 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
##
|
2
|
+
# Filter
|
3
|
+
#
|
4
|
+
module Outpost
|
5
|
+
module List
|
6
|
+
class Filter
|
7
|
+
BOOLEAN_COLLECT = [["Yes", 1], ["No", 0]]
|
8
|
+
|
9
|
+
attr_accessor :attribute, :collection, :title, :list
|
10
|
+
|
11
|
+
def initialize(attribute, list, options={})
|
12
|
+
@attribute = attribute.to_s
|
13
|
+
@list = list
|
14
|
+
@title = options[:title] || @attribute.titleize
|
15
|
+
|
16
|
+
collection = options[:collection]
|
17
|
+
@collection = begin
|
18
|
+
case collection
|
19
|
+
when NilClass
|
20
|
+
# TODO Automatically detect column type
|
21
|
+
when Proc
|
22
|
+
collection
|
23
|
+
when Symbol
|
24
|
+
send "_#{collection}_collection"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def _boolean_collection
|
33
|
+
-> { BOOLEAN_COLLECT }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/outpost/list.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Model
|
3
|
+
module Authentication
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_secure_password
|
8
|
+
|
9
|
+
before_validation :downcase_email, if: -> { self.email_changed? }
|
10
|
+
validates :name, presence: true
|
11
|
+
validates Outpost.config.authentication_attribute, presence: true, uniqueness: true
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def authenticate(login, unencrypted_password)
|
16
|
+
if user = self.send("find_by_#{Outpost.config.authentication_attribute}", login)
|
17
|
+
user.authenticate(unencrypted_password)
|
18
|
+
else
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Private: Downcase the user's e-mail
|
25
|
+
#
|
26
|
+
# Returns String of the e-mail
|
27
|
+
def downcase_email
|
28
|
+
if self.email.present?
|
29
|
+
self.email = self.email.downcase
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Model
|
3
|
+
module Authorization
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :user_permissions
|
8
|
+
has_many :permissions, through: :user_permissions
|
9
|
+
end
|
10
|
+
# Check if a user can manage the passed-in resource(s)
|
11
|
+
#
|
12
|
+
# If multiple resources are passed in, a user must be
|
13
|
+
# allowed to manage ALL of them in order for this to
|
14
|
+
# return true.
|
15
|
+
#
|
16
|
+
# Constants must be passed in.
|
17
|
+
#
|
18
|
+
def can_manage?(*resources)
|
19
|
+
self.is_superuser? or (allowed_resources & resources) == resources
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
|
24
|
+
def allowed_resources
|
25
|
+
@allowed_resources ||= begin
|
26
|
+
p = self.is_superuser? ? Permission.all : self.permissions
|
27
|
+
p.map { |p| p.resource.safe_constantize }.compact
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
##
|
2
|
+
# Identifier
|
3
|
+
#
|
4
|
+
# Some unique keys which can be used for routing
|
5
|
+
# and APIs
|
6
|
+
module Outpost
|
7
|
+
module Model
|
8
|
+
module Identifier
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def content_key
|
14
|
+
if self.respond_to? :table_name
|
15
|
+
self.table_name.gsub(/_/, "/")
|
16
|
+
else
|
17
|
+
self.name.tableize
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Wrappers for ActiveModel::Naming
|
22
|
+
# NewsStory => news_stories
|
23
|
+
def route_key
|
24
|
+
ActiveModel::Naming.route_key(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
# NewsStory => news_story
|
28
|
+
def singular_route_key
|
29
|
+
ActiveModel::Naming.singular_route_key(self)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Default obj_key pattern
|
34
|
+
def obj_key
|
35
|
+
@obj_key ||= [self.class.content_key,self.id || "new"].join(":")
|
36
|
+
end
|
37
|
+
end # Identifier
|
38
|
+
end # Model
|
39
|
+
end # Outpost
|
@@ -0,0 +1,23 @@
|
|
1
|
+
##
|
2
|
+
# Outpost::Model::Methods
|
3
|
+
#
|
4
|
+
# This could be renamed to something more specific
|
5
|
+
module Outpost
|
6
|
+
module Model
|
7
|
+
module Methods
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
def persisted_record
|
11
|
+
@persisted_record ||= begin
|
12
|
+
# If this record isn't persisted, return nil
|
13
|
+
return nil if !self.persisted?
|
14
|
+
|
15
|
+
# If attributes have been changed, then fetch
|
16
|
+
# the persisted record from the database
|
17
|
+
# Otherwise just use self
|
18
|
+
self.changed? ? self.class.find(self.id) : self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end # Methods
|
22
|
+
end # Model
|
23
|
+
end # Outpost
|
@@ -0,0 +1,63 @@
|
|
1
|
+
##
|
2
|
+
# Naming
|
3
|
+
#
|
4
|
+
# Some methods for naming things, and stuff
|
5
|
+
module Outpost
|
6
|
+
module Model
|
7
|
+
module Naming
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# NewsStory => News Story
|
12
|
+
def to_title
|
13
|
+
self.name.demodulize.titleize
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convert any AR object into a human-readable title
|
18
|
+
# Tries the attributes in config.title_attributes
|
19
|
+
# And falls back to "BlogEntry #99"
|
20
|
+
#
|
21
|
+
# This allows us to get a human-readable title regardless
|
22
|
+
# of what an object's "title" attribute happens to be.
|
23
|
+
#
|
24
|
+
# To define your own set of attributes, do so with the config
|
25
|
+
#
|
26
|
+
# Outpost.config.title_attributes = [:title, :full_name]
|
27
|
+
#
|
28
|
+
# The :simple_title method will automatically be added to the array
|
29
|
+
# and acts as the fallback.
|
30
|
+
#
|
31
|
+
# Usage:
|
32
|
+
#
|
33
|
+
# story = NewsStory.last #=> NewsStory(id: 900, title: "Cool Story, Bro")
|
34
|
+
# blog = Blog.last #=> Blog(id: 5, name: "Some Blog")
|
35
|
+
# photo = Photo.last #=> Photo(id: 10, url: "http://photos.com/kitty")
|
36
|
+
#
|
37
|
+
# story.to_title #=> "Cool Story, Bro"
|
38
|
+
# blog.to_title #=> "Some Blog"
|
39
|
+
# photo.to_title #=> "Photo #10"
|
40
|
+
#
|
41
|
+
def title_method
|
42
|
+
@title_method ||= begin
|
43
|
+
attributes = Outpost.config.title_attributes
|
44
|
+
attributes.find { |a| self.respond_to?(a) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_title
|
49
|
+
@to_title ||= self.send(self.title_method)
|
50
|
+
end
|
51
|
+
|
52
|
+
def simple_title
|
53
|
+
@simple_title ||= begin
|
54
|
+
if self.new_record?
|
55
|
+
"New #{self.class.to_title}"
|
56
|
+
else
|
57
|
+
"#{self.class.to_title} ##{self.id}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end # Naming
|
62
|
+
end # Model
|
63
|
+
end # Outpost
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Model
|
3
|
+
# Routing
|
4
|
+
#
|
5
|
+
# Provides easy access to any object's admin paths,
|
6
|
+
# and any class's admin paths.
|
7
|
+
#
|
8
|
+
# These methods are just delegations to your app's routes.
|
9
|
+
#
|
10
|
+
# Provides alias methods for non-GET routes:
|
11
|
+
#
|
12
|
+
# * admin_index_path => admin_create_path
|
13
|
+
# * admin_show_path => admin_update_path, admin_destroy_path
|
14
|
+
#
|
15
|
+
# So you can do, for example:
|
16
|
+
#
|
17
|
+
# POST admin_create_path
|
18
|
+
#
|
19
|
+
# Which would make more sense than `POST admin_index_path`,
|
20
|
+
# even though they are the same path.
|
21
|
+
module Routing
|
22
|
+
extend ActiveSupport::Concern
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
# /outpost/blog_entries/new
|
26
|
+
def admin_new_path
|
27
|
+
collection_route("new_outpost_#{self.singular_route_key}_path")
|
28
|
+
end
|
29
|
+
|
30
|
+
# http://kpcc.org/outpost/blog_entries/new
|
31
|
+
def admin_new_url
|
32
|
+
collection_route("new_outpost_#{self.singular_route_key}_url")
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# /outpost/blog_entries
|
37
|
+
def admin_index_path
|
38
|
+
collection_route("outpost_#{self.route_key}_path")
|
39
|
+
end
|
40
|
+
|
41
|
+
alias_method :admin_create_path, :admin_index_path
|
42
|
+
|
43
|
+
# http://kpcc.org/outpost/blog_entries
|
44
|
+
def admin_index_url
|
45
|
+
collection_route("outpost_#{self.route_key}_url")
|
46
|
+
end
|
47
|
+
|
48
|
+
alias_method :admin_create_url, :admin_index_url
|
49
|
+
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def collection_route(name)
|
54
|
+
Rails.application.routes.url_helpers.send(name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# /outpost/blog_entries/20/edit
|
60
|
+
def admin_edit_path
|
61
|
+
member_route("edit_outpost_#{self.class.singular_route_key}_path")
|
62
|
+
end
|
63
|
+
|
64
|
+
# http://kpcc.org/outpost/blog_entries/20/edit
|
65
|
+
def admin_edit_url
|
66
|
+
member_route("edit_outpost_#{self.class.singular_route_key}_url")
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# /outpost/blog_entries/20
|
71
|
+
def admin_show_path
|
72
|
+
member_route("outpost_#{self.class.singular_route_key}_path")
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method :admin_update_path, :admin_show_path
|
76
|
+
alias_method :admin_destroy_path, :admin_show_path
|
77
|
+
|
78
|
+
# http://kpcc.org/outpost/blog_entries/20
|
79
|
+
def admin_show_url
|
80
|
+
member_route("outpost_#{self.class.singular_route_key}_url")
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :admin_update_url, :admin_show_url
|
84
|
+
alias_method :admin_destroy_url, :admin_show_url
|
85
|
+
|
86
|
+
|
87
|
+
# Uses self.class::ROUTE_KEY to generate
|
88
|
+
# the front-end path to this object
|
89
|
+
# If an object doesn't have a front-end path,
|
90
|
+
# do not define a ROUTE_KEY on the class.
|
91
|
+
#
|
92
|
+
# If the object isn't public, then leave route_hash
|
93
|
+
# empty as well.
|
94
|
+
def public_path(options={})
|
95
|
+
if self.route_hash.present? && defined?(self.class::ROUTE_KEY)
|
96
|
+
Rails.application.routes.url_helpers.send(
|
97
|
+
"#{self.class::ROUTE_KEY}_path", options.merge!(self.route_hash))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
alias_method :link_path, :public_path
|
102
|
+
deprecate link_path: :public_path
|
103
|
+
|
104
|
+
|
105
|
+
# Override this method manually for each model.
|
106
|
+
# If the object isn't public, then don't override
|
107
|
+
# this method. #public_path checks for the presence
|
108
|
+
# of this object. By leaving it blank, you're also
|
109
|
+
# telling #public_path to be nil.
|
110
|
+
def route_hash
|
111
|
+
{}
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# http://scpr.org/blogs/2012/...
|
116
|
+
def public_url(options={})
|
117
|
+
if path = self.public_path(options)
|
118
|
+
File.join(
|
119
|
+
"http://#{Rails.application.default_url_options[:host]}", path)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
alias_method :remote_link_path, :public_url
|
124
|
+
deprecate remote_link_path: :public_url
|
125
|
+
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
# Don't try to build a route if the ID is nil.
|
130
|
+
# Should we instead be checking persistence?
|
131
|
+
def member_route(name)
|
132
|
+
if self.id
|
133
|
+
Rails.application.routes.url_helpers.send(name, self.id)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end # Routing
|
137
|
+
end # Model
|
138
|
+
end # Outpost
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Model
|
3
|
+
module Serializer
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# This method should be overridden
|
7
|
+
# Don't override as_json unless you don't
|
8
|
+
# want its baked-in goodies
|
9
|
+
def json
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Define some defaults for as_json
|
14
|
+
# Override +#json+ to add attributes
|
15
|
+
# or override any of these.
|
16
|
+
def as_json(*args)
|
17
|
+
super.merge({
|
18
|
+
"id" => self.obj_key,
|
19
|
+
"obj_key" => self.obj_key,
|
20
|
+
"link_path" => self.public_path,
|
21
|
+
"to_title" => self.to_title,
|
22
|
+
"edit_path" => self.admin_edit_path
|
23
|
+
}).merge(self.json.stringify_keys!)
|
24
|
+
end
|
25
|
+
end # JSON
|
26
|
+
end # Model
|
27
|
+
end # Outpost
|
@@ -0,0 +1,22 @@
|
|
1
|
+
##
|
2
|
+
# Outpost::Model
|
3
|
+
module Outpost
|
4
|
+
module Model
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
extend ActiveSupport::Autoload
|
7
|
+
|
8
|
+
autoload :Authentication
|
9
|
+
autoload :Authorization
|
10
|
+
autoload :Methods
|
11
|
+
autoload :Identifier
|
12
|
+
autoload :Routing
|
13
|
+
autoload :Naming
|
14
|
+
autoload :Serializer
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def outpost_model
|
18
|
+
include Methods, Identifier, Routing, Naming, Serializer
|
19
|
+
end
|
20
|
+
end # ClassMethods
|
21
|
+
end # Model
|
22
|
+
end # Outpost
|
data/lib/outpost/test.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Some test helpers
|
2
|
+
|
3
|
+
module Outpost
|
4
|
+
module Test
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# Populate the permissions table.
|
8
|
+
# Especially useful when using truncation strategy.
|
9
|
+
def create_permissions
|
10
|
+
created = []
|
11
|
+
|
12
|
+
Outpost.config.registered_models.each do |model|
|
13
|
+
if !Permission.exists?(resource: model)
|
14
|
+
created << Permission.create(resource: model)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
created
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/outpost-cms.rb
ADDED
data/lib/outpost.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require "outpost/engine"
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
require 'action_controller'
|
5
|
+
require 'action_view'
|
6
|
+
require 'action_view/helpers/form_builder'
|
7
|
+
|
8
|
+
require 'outpost/config'
|
9
|
+
|
10
|
+
module Outpost
|
11
|
+
extend ActiveSupport::Autoload
|
12
|
+
|
13
|
+
OBJ_KEY_REGEX = %r{([^:]+):(\d+)}
|
14
|
+
|
15
|
+
autoload :Controller
|
16
|
+
autoload :Model
|
17
|
+
autoload :Hook
|
18
|
+
autoload :Helpers
|
19
|
+
autoload :List
|
20
|
+
autoload :Breadcrumb, 'outpost/breadcrumbs'
|
21
|
+
autoload :Breadcrumbs
|
22
|
+
|
23
|
+
class << self
|
24
|
+
attr_writer :config
|
25
|
+
def config
|
26
|
+
@config ||= Outpost::Config.new
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO can we cache this in development?
|
30
|
+
def user_class
|
31
|
+
config.user_class.constantize
|
32
|
+
end
|
33
|
+
|
34
|
+
#--------------------
|
35
|
+
# Convert key from "app/model:id" to AppModel.find_by_id(id)
|
36
|
+
def obj_by_key(key)
|
37
|
+
if match = match_key(key)
|
38
|
+
model = model_classes[match[1]]
|
39
|
+
model.find_by_id(match[2]) if model
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#--------------------
|
44
|
+
# Same as #obj_by_key, but raises ActiveRecord::RecordNotFound
|
45
|
+
# if no object is found or if key doesn't match.
|
46
|
+
def obj_by_key!(key)
|
47
|
+
obj_by_key(key) or raise ActiveRecord::RecordNotFound
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def match_key(key)
|
54
|
+
key.to_s.match(OBJ_KEY_REGEX)
|
55
|
+
end
|
56
|
+
|
57
|
+
#--------------------
|
58
|
+
|
59
|
+
def model_classes
|
60
|
+
@model_classes ||= begin
|
61
|
+
klasses = {}
|
62
|
+
|
63
|
+
Outpost.config.registered_models.each do |name|
|
64
|
+
klass = name.constantize
|
65
|
+
klasses.merge!(klass.content_key => klass)
|
66
|
+
end
|
67
|
+
|
68
|
+
klasses
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
if defined?(ActiveRecord::Base)
|
75
|
+
ActiveRecord::Base.send :include, Outpost::Model
|
76
|
+
end
|
77
|
+
|
78
|
+
if defined?(ActionController::Base)
|
79
|
+
ActionController::Base.send :include, Outpost::Controller
|
80
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Outpost::PeopleController do
|
4
|
+
describe "current_user" do
|
5
|
+
it "looks up the ID stored in the session" do
|
6
|
+
user = create :user
|
7
|
+
controller.session[:user_id] = user.id
|
8
|
+
controller.current_user.should eq user
|
9
|
+
end
|
10
|
+
|
11
|
+
it "only finds user where can_login is true" do
|
12
|
+
user = create :user, can_login: true
|
13
|
+
controller.session[:user_id] = user.id
|
14
|
+
controller.current_user.should eq user
|
15
|
+
|
16
|
+
controller.instance_variable_set(:@current_user, nil)
|
17
|
+
nologin_user = create :user, can_login: false
|
18
|
+
controller.session[:user_id] = nologin_user.id
|
19
|
+
controller.current_user.should eq nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns nil if session is blank" do
|
23
|
+
controller.session[:user_id] = nil
|
24
|
+
controller.current_user.should eq nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "unsets the session and returns false if the user isn't found" do
|
28
|
+
controller.session[:user_id] = 999
|
29
|
+
controller.current_user.should eq nil
|
30
|
+
controller.session[:user_id].should eq nil
|
31
|
+
controller.instance_variable_get(:@current_user).should eq nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#-----------------
|
36
|
+
|
37
|
+
describe "require_login" do
|
38
|
+
context "current_user true" do
|
39
|
+
it "returns nil" do
|
40
|
+
user = create :user
|
41
|
+
controller.stub(:current_user) { user }
|
42
|
+
controller.require_login.should eq nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "current_user false" do
|
47
|
+
before :each do
|
48
|
+
controller.stub(:current_user) { nil }
|
49
|
+
controller.request.stub(:fullpath) { "/home" }
|
50
|
+
get :index
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sets the return_to to the request path" do
|
54
|
+
controller.session[:return_to].should eq "/home"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "redirects to login path if current_user is false" do
|
58
|
+
controller.response.should redirect_to outpost_login_path
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|