outpost-cms 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +295 -0
  3. data/Rakefile +26 -0
  4. data/app/assets/images/glyphicons-halflings-red.png +0 -0
  5. data/app/assets/javascripts/outpost/application.js +1 -0
  6. data/app/assets/javascripts/outpost/auto_slug_field.js.coffee +53 -0
  7. data/app/assets/javascripts/outpost/base.js.coffee +1 -0
  8. data/app/assets/javascripts/outpost/date_time_input.js.coffee +108 -0
  9. data/app/assets/javascripts/outpost/field_counter.js.coffee +93 -0
  10. data/app/assets/javascripts/outpost/field_manager.js.coffee +37 -0
  11. data/app/assets/javascripts/outpost/global_plugins.js.coffee +87 -0
  12. data/app/assets/javascripts/outpost/index_manager.js.coffee +88 -0
  13. data/app/assets/javascripts/outpost/notification.js.coffee +46 -0
  14. data/app/assets/javascripts/outpost/preview.js.coffee +60 -0
  15. data/app/assets/javascripts/outpost/templates/date_field.jst.eco +3 -0
  16. data/app/assets/javascripts/outpost/templates/loading.jst.eco +11 -0
  17. data/app/assets/javascripts/outpost/templates/slug_generate_button.jst.eco +1 -0
  18. data/app/assets/javascripts/outpost/templates/time_field.jst.eco +3 -0
  19. data/app/assets/javascripts/outpost/templates.js +1 -0
  20. data/app/assets/javascripts/outpost.js +32 -0
  21. data/app/assets/stylesheets/outpost/_base.css.scss +127 -0
  22. data/app/assets/stylesheets/outpost/_edit.css.scss +13 -0
  23. data/app/assets/stylesheets/outpost/_forms.css.scss +116 -0
  24. data/app/assets/stylesheets/outpost/_index.css.scss +68 -0
  25. data/app/assets/stylesheets/outpost/_utility.css.scss +16 -0
  26. data/app/assets/stylesheets/outpost/application.css.scss +1 -0
  27. data/app/assets/stylesheets/outpost/bootstrap/bootstrap.css.scss +49 -0
  28. data/app/assets/stylesheets/outpost/bootstrap/datepicker.css.scss +301 -0
  29. data/app/assets/stylesheets/outpost.css.scss +14 -0
  30. data/app/controllers/outpost/application_controller.rb +40 -0
  31. data/app/controllers/outpost/base_controller.rb +3 -0
  32. data/app/controllers/outpost/errors_controller.rb +9 -0
  33. data/app/controllers/outpost/home_controller.rb +2 -0
  34. data/app/controllers/outpost/resource_controller.rb +12 -0
  35. data/app/controllers/outpost/sessions_controller.rb +36 -0
  36. data/app/helpers/authorization_helper.rb +44 -0
  37. data/app/helpers/list_helper.rb +243 -0
  38. data/app/helpers/outpost_helper.rb +49 -0
  39. data/app/helpers/render_helper.rb +41 -0
  40. data/app/helpers/utility_helper.rb +136 -0
  41. data/app/inputs/date_time_input.rb +12 -0
  42. data/app/models/permission.rb +18 -0
  43. data/app/models/user_permission.rb +4 -0
  44. data/app/views/kaminari/bootstrap/_first_page.html.erb +3 -0
  45. data/app/views/kaminari/bootstrap/_gap.html.erb +3 -0
  46. data/app/views/kaminari/bootstrap/_last_page.html.erb +3 -0
  47. data/app/views/kaminari/bootstrap/_next_page.html.erb +3 -0
  48. data/app/views/kaminari/bootstrap/_page.html.erb +3 -0
  49. data/app/views/kaminari/bootstrap/_paginator.html.erb +17 -0
  50. data/app/views/kaminari/bootstrap/_prev_page.html.erb +3 -0
  51. data/app/views/layouts/outpost/application.html.erb +101 -0
  52. data/app/views/layouts/outpost/minimal.html.erb +26 -0
  53. data/app/views/outpost/errors/error_404.html.erb +1 -0
  54. data/app/views/outpost/errors/error_500.html.erb +8 -0
  55. data/app/views/outpost/home/dashboard.html.erb +1 -0
  56. data/app/views/outpost/resource/_errors.html.erb +11 -0
  57. data/app/views/outpost/resource/_extra_fields.html.erb +1 -0
  58. data/app/views/outpost/resource/_form_fields.html.erb +9 -0
  59. data/app/views/outpost/resource/edit.html.erb +44 -0
  60. data/app/views/outpost/resource/index.html.erb +22 -0
  61. data/app/views/outpost/resource/new.html.erb +21 -0
  62. data/app/views/outpost/resource/search.html.erb +1 -0
  63. data/app/views/outpost/resource/show.html.erb +1 -0
  64. data/app/views/outpost/sessions/new.html.erb +16 -0
  65. data/app/views/outpost/shared/_add_link.html.erb +1 -0
  66. data/app/views/outpost/shared/_breadcrumbs.html.erb +15 -0
  67. data/app/views/outpost/shared/_cancel_link.html.erb +1 -0
  68. data/app/views/outpost/shared/_columns.html.erb +5 -0
  69. data/app/views/outpost/shared/_filters.html.erb +16 -0
  70. data/app/views/outpost/shared/_flash_messages.html.erb +6 -0
  71. data/app/views/outpost/shared/_form_block.html.erb +18 -0
  72. data/app/views/outpost/shared/_form_nav.html.erb +12 -0
  73. data/app/views/outpost/shared/_headers.html.erb +16 -0
  74. data/app/views/outpost/shared/_index_header.html.erb +4 -0
  75. data/app/views/outpost/shared/_list_table.html.erb +7 -0
  76. data/app/views/outpost/shared/_modal.html.erb +16 -0
  77. data/app/views/outpost/shared/_navigation.html.erb +31 -0
  78. data/app/views/outpost/shared/_notice.html.erb +1 -0
  79. data/app/views/outpost/shared/_pagination.html.erb +2 -0
  80. data/app/views/outpost/shared/_preview_errors.html.erb +9 -0
  81. data/app/views/outpost/shared/_submit_row.html.erb +50 -0
  82. data/config/routes.rb +4 -0
  83. data/lib/action_view/helpers/form_builder.rb +71 -0
  84. data/lib/outpost/breadcrumbs.rb +73 -0
  85. data/lib/outpost/config.rb +63 -0
  86. data/lib/outpost/controller/actions.rb +72 -0
  87. data/lib/outpost/controller/authentication.rb +34 -0
  88. data/lib/outpost/controller/authorization.rb +28 -0
  89. data/lib/outpost/controller/callbacks.rb +14 -0
  90. data/lib/outpost/controller/custom_errors.rb +41 -0
  91. data/lib/outpost/controller/filtering.rb +22 -0
  92. data/lib/outpost/controller/helpers.rb +52 -0
  93. data/lib/outpost/controller/ordering.rb +46 -0
  94. data/lib/outpost/controller/preferences.rb +71 -0
  95. data/lib/outpost/controller.rb +123 -0
  96. data/lib/outpost/engine.rb +10 -0
  97. data/lib/outpost/helpers/naming.rb +22 -0
  98. data/lib/outpost/helpers.rb +6 -0
  99. data/lib/outpost/hook.rb +35 -0
  100. data/lib/outpost/list/base.rb +78 -0
  101. data/lib/outpost/list/column.rb +24 -0
  102. data/lib/outpost/list/filter.rb +37 -0
  103. data/lib/outpost/list.rb +15 -0
  104. data/lib/outpost/model/authentication.rb +34 -0
  105. data/lib/outpost/model/authorization.rb +32 -0
  106. data/lib/outpost/model/identifier.rb +39 -0
  107. data/lib/outpost/model/methods.rb +23 -0
  108. data/lib/outpost/model/naming.rb +63 -0
  109. data/lib/outpost/model/routing.rb +138 -0
  110. data/lib/outpost/model/serializer.rb +27 -0
  111. data/lib/outpost/model.rb +22 -0
  112. data/lib/outpost/test.rb +21 -0
  113. data/lib/outpost/version.rb +3 -0
  114. data/lib/outpost-cms.rb +2 -0
  115. data/lib/outpost.rb +80 -0
  116. data/lib/tasks/outpost_tasks.rake +7 -0
  117. data/spec/controllers/authentication_spec.rb +62 -0
  118. data/spec/controllers/sessions_controller_spec.rb +99 -0
  119. data/spec/factories.rb +31 -0
  120. data/spec/helpers/authorization_helper_spec.rb +47 -0
  121. data/spec/helpers/list_helper_spec.rb +74 -0
  122. data/spec/helpers/outpost_helper_spec.rb +5 -0
  123. data/spec/helpers/render_helper_spec.rb +19 -0
  124. data/spec/helpers/utility_helper_spec.rb +53 -0
  125. data/spec/internal/app/controllers/application_controller.rb +3 -0
  126. data/spec/internal/app/controllers/outpost/people_controller.rb +23 -0
  127. data/spec/internal/app/controllers/outpost/pidgeons_controller.rb +5 -0
  128. data/spec/internal/app/controllers/people_controller.rb +9 -0
  129. data/spec/internal/app/controllers/pidgeons_controller.rb +3 -0
  130. data/spec/internal/app/models/person.rb +10 -0
  131. data/spec/internal/app/models/pidgeon.rb +3 -0
  132. data/spec/internal/app/models/post.rb +4 -0
  133. data/spec/internal/app/models/user.rb +4 -0
  134. data/spec/internal/app/views/people/index.html.erb +7 -0
  135. data/spec/internal/app/views/people/show.html.erb +1 -0
  136. data/spec/internal/config/database.yml +3 -0
  137. data/spec/internal/config/initializers/configuration.rb +3 -0
  138. data/spec/internal/config/initializers/outpost.rb +6 -0
  139. data/spec/internal/config/routes.rb +16 -0
  140. data/spec/internal/db/combustion_test.sqlite +0 -0
  141. data/spec/internal/db/schema.rb +44 -0
  142. data/spec/internal/db/seeds.rb +14 -0
  143. data/spec/internal/log/test.log +59277 -0
  144. data/spec/internal/public/favicon.ico +0 -0
  145. data/spec/lib/breadcrumbs_spec.rb +54 -0
  146. data/spec/lib/config_spec.rb +76 -0
  147. data/spec/lib/controller/actions_spec.rb +5 -0
  148. data/spec/lib/controller/authorization_spec.rb +4 -0
  149. data/spec/lib/controller/callbacks_spec.rb +31 -0
  150. data/spec/lib/controller/helpers_spec.rb +33 -0
  151. data/spec/lib/controller_spec.rb +25 -0
  152. data/spec/lib/helpers/naming_spec.rb +10 -0
  153. data/spec/lib/hook_spec.rb +13 -0
  154. data/spec/lib/list/base_spec.rb +96 -0
  155. data/spec/lib/list/column_spec.rb +46 -0
  156. data/spec/lib/list/filter_spec.rb +44 -0
  157. data/spec/lib/model/authentication_spec.rb +29 -0
  158. data/spec/lib/model/authorization_spec.rb +66 -0
  159. data/spec/lib/model/identifier_spec.rb +51 -0
  160. data/spec/lib/model/methods_spec.rb +8 -0
  161. data/spec/lib/model/naming_spec.rb +55 -0
  162. data/spec/lib/model/routing_spec.rb +166 -0
  163. data/spec/lib/model/serializer_spec.rb +13 -0
  164. data/spec/lib/outpost_spec.rb +34 -0
  165. data/spec/models/permission_spec.rb +10 -0
  166. data/spec/models/user_permission_spec.rb +4 -0
  167. data/spec/spec_helper.rb +22 -0
  168. 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
@@ -0,0 +1,15 @@
1
+ ##
2
+ # Outpost::List
3
+ module Outpost
4
+ module List
5
+ extend ActiveSupport::Autoload
6
+
7
+ DEFAULT_ORDER = "id"
8
+ DEFAULT_SORT_MODE = "desc"
9
+ DEFAULT_PER_PAGE = 25
10
+
11
+ autoload :Base
12
+ autoload :Column
13
+ autoload :Filter
14
+ end
15
+ end
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ module Outpost
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,2 @@
1
+ # Trick rubygems
2
+ require 'outpost'
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,7 @@
1
+ namespace :outpost do
2
+ desc "Update Permissions table with Outpost registered models"
3
+ task :permissions => [:environment] do
4
+ added = Outpost::Test.create_permissions
5
+ puts "Added: #{added}"
6
+ end
7
+ 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