caboose-cms 0.0.2
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.
- data/MIT-LICENSE +20 -0
- data/README.md +4 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/caboose/application.js +36 -0
- data/app/assets/javascripts/caboose/login.js +21 -0
- data/app/assets/javascripts/caboose/permissions.js +0 -0
- data/app/assets/javascripts/caboose/roles.js +35 -0
- data/app/assets/javascripts/caboose/users.js +38 -0
- data/app/assets/stylesheets/caboose/application.css +15 -0
- data/app/assets/stylesheets/caboose/caboose.css +28 -0
- data/app/controllers/caboose/admin_controller.rb +19 -0
- data/app/controllers/caboose/application_controller.rb +109 -0
- data/app/controllers/caboose/login_controller.rb +40 -0
- data/app/controllers/caboose/logout_controller.rb +9 -0
- data/app/controllers/caboose/pages_controller.rb +304 -0
- data/app/controllers/caboose/permissions_controller.rb +83 -0
- data/app/controllers/caboose/roles_controller.rb +109 -0
- data/app/controllers/caboose/users_controller.rb +117 -0
- data/app/helpers/caboose/application_helper.rb +4 -0
- data/app/helpers/caboose/permissions_helper.rb +4 -0
- data/app/models/caboose/approval_request.rb +13 -0
- data/app/models/caboose/asset.rb +23 -0
- data/app/models/caboose/caboose_plugin.rb +15 -0
- data/app/models/caboose/menu_block.rb +6 -0
- data/app/models/caboose/page.rb +329 -0
- data/app/models/caboose/page_bar_generator.rb +157 -0
- data/app/models/caboose/page_permission.rb +7 -0
- data/app/models/caboose/permission.rb +14 -0
- data/app/models/caboose/role.rb +50 -0
- data/app/models/caboose/std_class.rb +8 -0
- data/app/models/caboose/user.rb +47 -0
- data/app/views/caboose/admin/index.html.erb +5 -0
- data/app/views/caboose/application/show.html.erb +2 -0
- data/app/views/caboose/extras/error.html.erb +2 -0
- data/app/views/caboose/extras/error404.html.erb +0 -0
- data/app/views/caboose/login/index.html.erb +26 -0
- data/app/views/caboose/pages/edit.html.erb +45 -0
- data/app/views/caboose/pages/index.html.erb +34 -0
- data/app/views/caboose/pages/new.html.erb +23 -0
- data/app/views/caboose/pages/show.html.erb +2 -0
- data/app/views/caboose/pages/update_pic.html.erb +16 -0
- data/app/views/caboose/pages/update_resume.html.erb +14 -0
- data/app/views/caboose/permissions/edit.html.erb +6 -0
- data/app/views/caboose/permissions/index.html.erb +25 -0
- data/app/views/caboose/permissions/new.html.erb +5 -0
- data/app/views/caboose/permissions/show.html.erb +15 -0
- data/app/views/caboose/roles/edit.html.erb +36 -0
- data/app/views/caboose/roles/index.html.erb +17 -0
- data/app/views/caboose/roles/new.html.erb +16 -0
- data/app/views/caboose/roles/show.html.erb +20 -0
- data/app/views/caboose/users/edit.html.erb +45 -0
- data/app/views/caboose/users/index.html.erb +34 -0
- data/app/views/caboose/users/new.html.erb +22 -0
- data/app/views/caboose/users/update_pic.html.erb +16 -0
- data/app/views/caboose/users/update_resume.html.erb +14 -0
- data/app/views/layouts/caboose/application.html.erb +24 -0
- data/app/views/layouts/caboose/caboose.html.erb +24 -0
- data/app/views/layouts/caboose/error404.html.erb +2 -0
- data/app/views/layouts/caboose/station.html.erb +28 -0
- data/config/routes.rb +48 -0
- data/db/migrate/20130421000000_drop_all_caboose.rb +16 -0
- data/db/migrate/20130422000000_create_caboose.rb +147 -0
- data/lib/caboose.rb +26 -0
- data/lib/caboose/engine.rb +24 -0
- data/lib/caboose/version.rb +3 -0
- data/lib/tasks/caboose_tasks.rake +4 -0
- data/test/caboose_test.rb +7 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +25 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- metadata +241 -0
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2013 YOURNAME
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'rdoc/task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require 'rdoc/rdoc'
|
|
11
|
+
require 'rake/rdoctask'
|
|
12
|
+
RDoc::Task = Rake::RDocTask
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
+
rdoc.title = 'Caboose'
|
|
18
|
+
rdoc.options << '--line-numbers'
|
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
24
|
+
load 'rails/tasks/engine.rake'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Bundler::GemHelper.install_tasks
|
|
29
|
+
|
|
30
|
+
require 'rake/testtask'
|
|
31
|
+
|
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
|
33
|
+
t.libs << 'lib'
|
|
34
|
+
t.libs << 'test'
|
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
|
36
|
+
t.verbose = false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
task :default => :test
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// the compiled file.
|
|
9
|
+
//
|
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
|
12
|
+
//
|
|
13
|
+
//= require caboose_before
|
|
14
|
+
//= require jquery
|
|
15
|
+
//= require jquery_ujs
|
|
16
|
+
//= require jquery-ui
|
|
17
|
+
//= require class
|
|
18
|
+
//= require model/model
|
|
19
|
+
//= require model/attribute
|
|
20
|
+
//= require model/form
|
|
21
|
+
//= require model/form/embedded
|
|
22
|
+
//= require model/attribute/checkbox-multiple
|
|
23
|
+
//= require model/attribute/checkbox
|
|
24
|
+
//= require model/attribute/date-time
|
|
25
|
+
//= require model/attribute/file
|
|
26
|
+
//= require model/attribute/hidden
|
|
27
|
+
//= require model/attribute/image
|
|
28
|
+
//= require model/attribute/password
|
|
29
|
+
//= require model/attribute/radio
|
|
30
|
+
//= require model/attribute/rich-text
|
|
31
|
+
//= require model/attribute/select
|
|
32
|
+
//= require model/attribute/texarea
|
|
33
|
+
//= require model/attribute/textjs
|
|
34
|
+
//= require model/attribute/time
|
|
35
|
+
//= require model/attribute/video
|
|
36
|
+
//= require caboose_after
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
function login()
|
|
3
|
+
{
|
|
4
|
+
$('#message').html("<p class='loading'>Logging in...</p>");
|
|
5
|
+
|
|
6
|
+
$.ajax({
|
|
7
|
+
url: '/login',
|
|
8
|
+
type: 'post',
|
|
9
|
+
data: $('#login_form').serialize(),
|
|
10
|
+
success: function(resp) {
|
|
11
|
+
if (resp.error)
|
|
12
|
+
$('#message').html("<p class='note error'>" + resp.error + "</p>");
|
|
13
|
+
else if (resp.redirect != false)
|
|
14
|
+
window.location = resp.redirect;
|
|
15
|
+
},
|
|
16
|
+
error: function() {
|
|
17
|
+
$('#message').html("<p class='note error'>Error</p>");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
Caboose.Role = function(){};
|
|
3
|
+
|
|
4
|
+
Caboose.Role.add = function()
|
|
5
|
+
{
|
|
6
|
+
$('#message').html("<p class='loading'>Adding role...</p>");
|
|
7
|
+
|
|
8
|
+
$.ajax({
|
|
9
|
+
url: '/roles',
|
|
10
|
+
type: 'post',
|
|
11
|
+
data: $('#new_role_form').serialize(),
|
|
12
|
+
success: Caboose.ajax_success,
|
|
13
|
+
error: Caboose.ajax_error
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
Caboose.Role.delete = function(role_id, confirm)
|
|
18
|
+
{
|
|
19
|
+
if (!confirm)
|
|
20
|
+
{
|
|
21
|
+
Caboose.confirm({
|
|
22
|
+
message: "Are you sure you want to delete the role? This can't be undone.",
|
|
23
|
+
yes: function() { Caboose.Role.delete(role_id, true) }
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
$('#message').html("<p class='loading'>Deleting role...</p>");
|
|
28
|
+
|
|
29
|
+
$.ajax({
|
|
30
|
+
url: '/roles/' + role_id,
|
|
31
|
+
type: 'delete',
|
|
32
|
+
success: Caboose.ajax_success,
|
|
33
|
+
error: Caboose.ajax_error
|
|
34
|
+
});
|
|
35
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
Nine
|
|
4
|
+
Caboose.User = function(){};
|
|
5
|
+
|
|
6
|
+
Caboose.User.add = function()
|
|
7
|
+
{
|
|
8
|
+
$('#message').html("<p class='loading'>Adding user...</p>");
|
|
9
|
+
|
|
10
|
+
$.ajax({
|
|
11
|
+
url: '/users',
|
|
12
|
+
type: 'post',
|
|
13
|
+
data: $('#new_user_form').serialize(),
|
|
14
|
+
success: Caboose.ajax_success,
|
|
15
|
+
error: Caboose.ajax_error
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Caboose.User.delete = function(user_id, confirm)
|
|
20
|
+
{
|
|
21
|
+
if (!confirm)
|
|
22
|
+
{
|
|
23
|
+
Caboose.confirm({
|
|
24
|
+
message: "Are you sure you want to delete the user? This can't be undone.",
|
|
25
|
+
yes: function() { Caboose.User.delete(user_id, true) }
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
$('#message').html("<p class='loading'>Deleting user...</p>");
|
|
30
|
+
|
|
31
|
+
$.ajax({
|
|
32
|
+
url: '/users/' + user_id,
|
|
33
|
+
type: 'delete',
|
|
34
|
+
success: Caboose.ajax_success,
|
|
35
|
+
error: Caboose.ajax_error
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
*/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
|
10
|
+
*
|
|
11
|
+
*= require caboose_before
|
|
12
|
+
*= require model
|
|
13
|
+
*= require caboose/caboose
|
|
14
|
+
*= require caboose_after
|
|
15
|
+
*/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
body {
|
|
3
|
+
font-family: Helvetica, Tahoma, Arial;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
#wrapper {
|
|
7
|
+
width: 960px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.page_links {
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.page_links a {
|
|
15
|
+
display: inline-block;
|
|
16
|
+
padding: 4px 8px;
|
|
17
|
+
border: #efefef 1px solid;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.page_links .middle_links a {
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.page_links span.current_page {
|
|
25
|
+
display: inline-block;
|
|
26
|
+
padding: 4px 8px;
|
|
27
|
+
font-weight: bold;
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
module Caboose
|
|
3
|
+
class AdminController < ApplicationController
|
|
4
|
+
|
|
5
|
+
# GET /admin
|
|
6
|
+
def index
|
|
7
|
+
return if !user_is_allowed('admin', 'view')
|
|
8
|
+
|
|
9
|
+
@mods = [
|
|
10
|
+
{ 'href' => '/admin/users' , 'text' => 'Users' },
|
|
11
|
+
{ 'href' => '/admin/roles' , 'text' => 'Roles' },
|
|
12
|
+
{ 'href' => '/admin/permissions' , 'text' => 'Permissions' }
|
|
13
|
+
]
|
|
14
|
+
@mods = Caboose.plugin_hook('admin_nav', @mods)
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
module Caboose
|
|
2
|
+
class ApplicationController < ActionController::Base
|
|
3
|
+
|
|
4
|
+
protect_from_forgery
|
|
5
|
+
before_filter :before_before_action
|
|
6
|
+
|
|
7
|
+
def before_before_action
|
|
8
|
+
|
|
9
|
+
# Try to find the page
|
|
10
|
+
@page = Page.page_with_uri(request.fullpath)
|
|
11
|
+
|
|
12
|
+
session['use_redirect_urls'] = true if session['use_redirect_urls'].nil?
|
|
13
|
+
|
|
14
|
+
@crumb_trail = Caboose::Page.crumb_trail(@page)
|
|
15
|
+
@subnav = {}
|
|
16
|
+
@actions = {}
|
|
17
|
+
@tasks = {}
|
|
18
|
+
@page_tasks = {}
|
|
19
|
+
@is_real_page = false
|
|
20
|
+
|
|
21
|
+
# Sets an instance variable of the logged in user
|
|
22
|
+
@logged_in_user = logged_in_user
|
|
23
|
+
|
|
24
|
+
before_action
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# To be overridden by the child controllers
|
|
28
|
+
def before_action
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Logs in a user
|
|
32
|
+
def login_user(user)
|
|
33
|
+
session["app_user"] = user
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Returns whether or not a user is logged in
|
|
37
|
+
def logged_in?
|
|
38
|
+
#return true if !session["app_user"].nil? && session["app_user"].id != -1
|
|
39
|
+
validate_token
|
|
40
|
+
return true if !session["app_user"].nil? && session["app_user"].id != -1
|
|
41
|
+
return false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Checks to see if a token is given. If so, it tries to validate the token
|
|
45
|
+
# and log the user in.
|
|
46
|
+
def validate_token
|
|
47
|
+
token = params[:token]
|
|
48
|
+
return false if token.nil?
|
|
49
|
+
|
|
50
|
+
user = User.validate_token(token)
|
|
51
|
+
return false if user.nil?
|
|
52
|
+
|
|
53
|
+
login_user(user)
|
|
54
|
+
return true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns the currently logged in user
|
|
58
|
+
def logged_in_user
|
|
59
|
+
if (!logged_in?)
|
|
60
|
+
return User.find(User::LOGGED_OUT_USER_ID)
|
|
61
|
+
end
|
|
62
|
+
#return nil if !logged_in?
|
|
63
|
+
return session["app_user"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Checks to see if a user has permission to perform the given action
|
|
67
|
+
# on the given resource.
|
|
68
|
+
# Redirects to login if not logged in.
|
|
69
|
+
# Redirects to error page with message if not allowed.
|
|
70
|
+
def user_is_allowed(resource, action)
|
|
71
|
+
if (!logged_in?)
|
|
72
|
+
redirect_to "/login?return_url=" + URI.encode(request.fullpath)
|
|
73
|
+
return
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
@user = logged_in_user
|
|
77
|
+
if (!@user.is_allowed(resource, action))
|
|
78
|
+
@error = "You don't have permission to " + action + " " + resource
|
|
79
|
+
render :template => "caboose/extras/error"
|
|
80
|
+
return false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
return true
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Removes a given parameter from a URL querystring
|
|
87
|
+
def reject_param(url, param)
|
|
88
|
+
arr = url.split('?')
|
|
89
|
+
return url if (arr.count == 1)
|
|
90
|
+
qs = arr[1].split('&').reject { |pair| pair.split(/[=;]/).first == param }
|
|
91
|
+
url2 = arr[0]
|
|
92
|
+
url2 += "?" + qs.join('&') if qs.count > 0
|
|
93
|
+
return url2
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#def auth_or_error(message)
|
|
97
|
+
# if (!logged_in?)
|
|
98
|
+
# redirect_to "/login?return_url=#{request.request_uri}" and return false
|
|
99
|
+
# end
|
|
100
|
+
# redirect_to "/error?message=#{message}"
|
|
101
|
+
#end
|
|
102
|
+
|
|
103
|
+
def var(key)
|
|
104
|
+
v = Var.where(:key => key).first
|
|
105
|
+
return "" if v.nil?
|
|
106
|
+
return v.val
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Caboose
|
|
2
|
+
class LoginController < Caboose::ApplicationController
|
|
3
|
+
|
|
4
|
+
# GET /login
|
|
5
|
+
def index
|
|
6
|
+
@return_url = params[:return_url].nil? ? "/" : params[:return_url];
|
|
7
|
+
redirect_to @return_url if logged_in?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# POST /login
|
|
11
|
+
def login
|
|
12
|
+
|
|
13
|
+
@resp = StdClass.new('error' => '', 'redirect' => '')
|
|
14
|
+
@return_url = params[:return_url].nil? ? "/" : params[:return_url]
|
|
15
|
+
|
|
16
|
+
if (logged_in?)
|
|
17
|
+
@resp.error = "Already logged in"
|
|
18
|
+
else
|
|
19
|
+
@username = params[:username]
|
|
20
|
+
@password = params[:password]
|
|
21
|
+
|
|
22
|
+
if (@username.nil? || @password.nil? || @password.strip.length == 0)
|
|
23
|
+
@resp.error = "Invalid credentials"
|
|
24
|
+
else
|
|
25
|
+
|
|
26
|
+
@password = Digest::SHA1.hexdigest(Caboose::salt + @password)
|
|
27
|
+
user = User.where(:username => @username, :password => @password).first
|
|
28
|
+
|
|
29
|
+
if (user.nil?)
|
|
30
|
+
@resp.error = "Invalid credentials"
|
|
31
|
+
else
|
|
32
|
+
login_user(user)
|
|
33
|
+
@resp.redirect = @return_url
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
render json: @resp
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
|
|
2
|
+
module Caboose
|
|
3
|
+
class PagesController < ApplicationController
|
|
4
|
+
|
|
5
|
+
def before_action
|
|
6
|
+
@page = Page.page_with_uri('/admin')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# GET /pages
|
|
10
|
+
def index
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# GET /pages/:id
|
|
14
|
+
def show
|
|
15
|
+
|
|
16
|
+
# Find the page with an exact URI match
|
|
17
|
+
page = Page.page_with_uri(request.fullpath, false)
|
|
18
|
+
Caboose.log(page)
|
|
19
|
+
|
|
20
|
+
if (!page)
|
|
21
|
+
asset
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
user = logged_in_user
|
|
26
|
+
if (!user.is_allowed(page, 'view'))
|
|
27
|
+
if (user.id == User.LOGGED_OUT_USER_ID)
|
|
28
|
+
redirect_to "/login?return_url=" + URI.encode(request.fullpath)
|
|
29
|
+
return
|
|
30
|
+
else
|
|
31
|
+
page.title = 'Access Denied'
|
|
32
|
+
page.content = "<p class='note error'>You do not have access to view this page.</p>"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if (session['use_redirect_urls'] && !page.redirect_url.nil? && page.redirect_url.strip.length > 0)
|
|
37
|
+
redirect_to page.redirect_url
|
|
38
|
+
return
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
page.content = Caboose.plugin_hook('page_content', page.content)
|
|
42
|
+
@page = page
|
|
43
|
+
@user = user
|
|
44
|
+
is_admin = @user.is_allowed('all', 'all')
|
|
45
|
+
|
|
46
|
+
@crumb_trail = Caboose::Page.crumb_trail(@page)
|
|
47
|
+
@subnav = Caboose::Page.subnav(@page, session['use_redirect_urls'], @user)
|
|
48
|
+
@actions = Caboose::Page.permissible_actions(@user.id, @page.id)
|
|
49
|
+
@tasks = {}
|
|
50
|
+
@page_tasks = {}
|
|
51
|
+
|
|
52
|
+
if (@actions.include?('edit') || is_admin)
|
|
53
|
+
@page_tasks["/pages/#{@page.id}/sitemap"] = 'Site Map This Page'
|
|
54
|
+
@page_tasks["/pages/#{@page.id}/edit"] = 'Edit Page Content'
|
|
55
|
+
@page_tasks["/pages/#{@page.id}/edit-settings"] = 'Edit Page Settings'
|
|
56
|
+
end
|
|
57
|
+
if (@user.is_allowed('pages', 'add') || is_admin)
|
|
58
|
+
@page_tasks["/pages/new?parent_id=#{@page.id}"] = 'New Page'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#@subnav.links = @tasks.collect {|href, task| {'href' => href, 'text' => task, 'is_current' => uri == href}}
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def asset
|
|
66
|
+
|
|
67
|
+
uri = uri.to_s.gsub(/^(.*?)\?.*?$/, '\1')
|
|
68
|
+
uri.chop! if uri.end_with?('/')
|
|
69
|
+
uri[0] = '' if uri.starts_with?('/')
|
|
70
|
+
|
|
71
|
+
page = Page.page_with_uri(File.dirname(uri), false)
|
|
72
|
+
if (page.nil? || !page)
|
|
73
|
+
render :file => "caboose/extras/error404", :layout => "caboose/error404"
|
|
74
|
+
return
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
asset = Asset.where(:page_id => page.id, :filename => File.basename(uri)).first
|
|
78
|
+
if (asset.nil?)
|
|
79
|
+
render :file => "caboose/extras/error404", :layout => "caboose/error404"
|
|
80
|
+
return
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
user = logged_in_user
|
|
84
|
+
if (!Page.is_allowed(user, asset.page_id, 'view'))
|
|
85
|
+
render "caboose/pages/asset_no_permission"
|
|
86
|
+
return
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
Caboose.log(Caboose::assets_path, 'Caboose::assets_path')
|
|
90
|
+
path = Caboose::assets_path.join("#{asset.id}.#{asset.extension}")
|
|
91
|
+
Caboose.log("Sending asset #{path}")
|
|
92
|
+
#send_file(path)
|
|
93
|
+
#send_file(path, :filename => "your_document.pdf", :type => "application/pdf")
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
#$path = ASSETS_PATH ."/". $asset->id .".". $asset->extension
|
|
97
|
+
#
|
|
98
|
+
#$finfo = finfo_open(FILEINFO_MIME_TYPE) // return mime type ala mimetype extension
|
|
99
|
+
#$mime = finfo_file($finfo, $path)
|
|
100
|
+
#finfo_close($finfo)
|
|
101
|
+
#
|
|
102
|
+
#header("X-Sendfile: $path")
|
|
103
|
+
#header("Content-Type: $mime")
|
|
104
|
+
#header("Content-Disposition: inline filename=\"$asset->filename\"")
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# GET /pages/new
|
|
109
|
+
def new
|
|
110
|
+
return if !user_is_allowed('pages', 'add')
|
|
111
|
+
@pages = Page.new
|
|
112
|
+
@parent_id = params[:parent_id].nil? ? params[:parent_id] : -1
|
|
113
|
+
render :layout => 'caboose/caboose'
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# GET /pages/1/edit
|
|
117
|
+
def edit
|
|
118
|
+
return if !user_is_allowed('pages', 'edit')
|
|
119
|
+
@page = Page.find(params[:id])
|
|
120
|
+
render :layout => 'caboose/caboose'
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# POST /pages
|
|
124
|
+
def create
|
|
125
|
+
return if !user_is_allowed('pages', 'add')
|
|
126
|
+
|
|
127
|
+
resp = Caboose::StdClass.new({
|
|
128
|
+
'error' => nil,
|
|
129
|
+
'redirect' => nil
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
parent_id = params[:parent_id]
|
|
133
|
+
title = params[:title]
|
|
134
|
+
|
|
135
|
+
if (title.strip.length == 0)
|
|
136
|
+
resp.error = "A page title is required."
|
|
137
|
+
elsif (!logged_in_user.is_allowed('all', 'all') &&
|
|
138
|
+
!Page.page_ids_with_permission(logged_in_user, 'edit' ).include?(parent_id) &&
|
|
139
|
+
!Page.page_ids_with_permission(logged_in_user, 'approve').include?(parent_id))
|
|
140
|
+
resp.error = "You don't have permission to add a page there."
|
|
141
|
+
end
|
|
142
|
+
if (!resp.error.nil?)
|
|
143
|
+
render json: resp
|
|
144
|
+
return
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
parent = Caboose::Page.find(parent_id)
|
|
148
|
+
|
|
149
|
+
page = Caboose::Page.new
|
|
150
|
+
page.title = title
|
|
151
|
+
page.parent_id = parent_id
|
|
152
|
+
page.hide = true
|
|
153
|
+
page.content_format = Caboose::Page::CONTENT_FORMAT_HTML
|
|
154
|
+
|
|
155
|
+
i = 0
|
|
156
|
+
begin
|
|
157
|
+
page.slug = Page.slug(page.title + (i > 0 ? " #{i}" : ""))
|
|
158
|
+
page.uri = parent.parent_id == -1 ? page.slug : "#{parent.uri}/#{page.slug}"
|
|
159
|
+
i = i+1
|
|
160
|
+
end while (Page.where(:uri => page.uri).count > 0 && i < 10)
|
|
161
|
+
|
|
162
|
+
page.save
|
|
163
|
+
|
|
164
|
+
# Set the new page's permissions
|
|
165
|
+
viewers = Caboose::PagePermission.where({ :page_id => parent.id, :action => 'view' }).pluck(:role_id)
|
|
166
|
+
editors = Caboose::PagePermission.where({ :page_id => parent.id, :action => 'edit' }).pluck(:role_id)
|
|
167
|
+
Caboose::Page.update_authorized_for_action(page.id, 'view', viewers)
|
|
168
|
+
Caboose::Page.update_authorized_for_action(page.id, 'edit', editors)
|
|
169
|
+
|
|
170
|
+
# Send back the response
|
|
171
|
+
resp.redirect = "/pages/#{page.id}/edit"
|
|
172
|
+
render json: resp
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# PUT /pages/1
|
|
176
|
+
def update
|
|
177
|
+
return if !user_is_allowed('pages', 'edit')
|
|
178
|
+
|
|
179
|
+
resp = StdClass.new({'attributes' => {}})
|
|
180
|
+
page = Page.find(params[:id])
|
|
181
|
+
|
|
182
|
+
save = true
|
|
183
|
+
user = logged_in_user
|
|
184
|
+
params.each do |name,value|
|
|
185
|
+
case name
|
|
186
|
+
when 'parent_id'
|
|
187
|
+
if (page.id == value)
|
|
188
|
+
resp.error = "The page's parent cannot be itself."
|
|
189
|
+
elsif (Page.is_child(page.id, value))
|
|
190
|
+
resp.error = "You can't set the current page's parent to be one of its child pages."
|
|
191
|
+
elsif (value != page.parent_id)
|
|
192
|
+
p = Page.find(value)
|
|
193
|
+
if (!user.is_allowed(p, 'edit'))
|
|
194
|
+
resp.error = "You don't have access to put the current page there."
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
if (resp.error.length > 0)
|
|
198
|
+
save = false
|
|
199
|
+
else
|
|
200
|
+
parent = Page.find(value)
|
|
201
|
+
Page.update_parent(page.id, value)
|
|
202
|
+
resp.attributes['parent_id'] = { 'text' => parent.title }
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
when 'title', 'menu_title', 'alias', 'redirect_url', 'hide',
|
|
206
|
+
'content_format', 'custom_css', 'custom_js', 'layout',
|
|
207
|
+
'seo_title', 'meta_description', 'fb_description', 'gp_description', 'canonical_url'
|
|
208
|
+
|
|
209
|
+
page[name.to_sym] = value
|
|
210
|
+
|
|
211
|
+
when 'meta_robots'
|
|
212
|
+
if (value.include?('index') && value.include?('noindex'))
|
|
213
|
+
resp.error = "You can't have both index and noindex"
|
|
214
|
+
save = false
|
|
215
|
+
elsif (value.include?('follow') && value.include?('nofollow'))
|
|
216
|
+
resp.error = "You can't have both follow and nofollow"
|
|
217
|
+
save = false
|
|
218
|
+
else
|
|
219
|
+
page.meta_robots = value.join(', ')
|
|
220
|
+
resp.attributes['meta_robots'] = { 'text' => page.meta_robots }
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
when 'content'
|
|
224
|
+
page.content = value.strip.gsub(/<meta.*?>/, '').gsub(/<link.*?>/, '').gsub(/\<\!--[\S\s]*?--\>/, '')
|
|
225
|
+
|
|
226
|
+
when 'slug'
|
|
227
|
+
page.slug = Page.slug(value.strip.length > 0 ? value : page.title)
|
|
228
|
+
resp.attributes['slug'] = { 'value' => page.slug }
|
|
229
|
+
|
|
230
|
+
when 'custom_sort_children'
|
|
231
|
+
if (value == 0)
|
|
232
|
+
page.children.each do |p|
|
|
233
|
+
p.sort_order = 1
|
|
234
|
+
p.save
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
page.custom_sort_children = value
|
|
238
|
+
|
|
239
|
+
when 'viewers'
|
|
240
|
+
Page.update_authorized_for_action(page.id, 'view', value)
|
|
241
|
+
when 'editors'
|
|
242
|
+
Page.update_authorized_for_action(page.id, 'edit', value)
|
|
243
|
+
when 'approvers'
|
|
244
|
+
Page.update_authorized_for_action(page.id, 'approve', value)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
resp.success = save && page.save
|
|
249
|
+
render json: resp
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# DELETE /pages/1
|
|
253
|
+
def destroy
|
|
254
|
+
return if !user_is_allowed('pages', 'delete')
|
|
255
|
+
user = Page.find(params[:id])
|
|
256
|
+
user.destroy
|
|
257
|
+
|
|
258
|
+
resp = StdClass.new({
|
|
259
|
+
'redirect' => '/pages'
|
|
260
|
+
})
|
|
261
|
+
render json: resp
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def sitemap_options
|
|
265
|
+
parent_id = params[:parent_id]
|
|
266
|
+
top_page = Page.index_page
|
|
267
|
+
p = !parent_id.nil? ? Page.find(parent_id) : top_page
|
|
268
|
+
options = []
|
|
269
|
+
sitemap_helper(top_page, options)
|
|
270
|
+
|
|
271
|
+
render json: options
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def sitemap_helper(page, options, prefix = '')
|
|
275
|
+
options << { 'value' => page.id, 'text' => prefix + page.title }
|
|
276
|
+
page.children.each do |kid|
|
|
277
|
+
sitemap_helper(kid, options, prefix + ' - ')
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def robots_options
|
|
282
|
+
options = [
|
|
283
|
+
{ 'value' => 'index' , 'text' => 'index' },
|
|
284
|
+
{ 'value' => 'noindex' , 'text' => 'noindex' },
|
|
285
|
+
{ 'value' => 'follow' , 'text' => 'follow' },
|
|
286
|
+
{ 'value' => 'nofollow' , 'text' => 'nofollow' },
|
|
287
|
+
{ 'value' => 'nosnippet' , 'text' => 'nosnippet' },
|
|
288
|
+
{ 'value' => 'noodp' , 'text' => 'noodp' },
|
|
289
|
+
{ 'value' => 'noarchive' , 'text' => 'noarchive' }
|
|
290
|
+
]
|
|
291
|
+
render json: options
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def content_format_options
|
|
295
|
+
options = [
|
|
296
|
+
{ 'value' => 'html', 'text' => 'html' },
|
|
297
|
+
{ 'value' => 'text', 'text' => 'text' },
|
|
298
|
+
{ 'value' => 'ruby', 'text' => 'ruby' }
|
|
299
|
+
]
|
|
300
|
+
render json: options
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
end
|