rxcms-podio_plugin 0.3.0
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +29 -0
- data/app/assets/javascripts/alliance_podio_plugin/configure.js +413 -0
- data/app/assets/javascripts/alliance_podio_plugin/engine.js +2 -0
- data/app/assets/javascripts/alliance_podio_plugin/installer.js +26 -0
- data/app/controllers/engine_controller.rb +98 -0
- data/app/controllers/installer_controller.rb +124 -0
- data/app/controllers/podio_controller.rb +205 -0
- data/app/controllers/services_controller.rb +153 -0
- data/app/controllers/sessions_controller.rb +120 -0
- data/app/helpers/plugin_helper.rb +30 -0
- data/app/models/abstract_application.rb +29 -0
- data/app/models/abstract_item.rb +207 -0
- data/app/models/abstract_organization.rb +12 -0
- data/app/models/abstract_space.rb +4 -0
- data/app/views/engine/configure.html.erb +184 -0
- data/app/views/engine/index.html.erb +1 -0
- data/app/views/engine/installer.html.erb +33 -0
- data/app/views/layouts/application.html.erb +1 -0
- data/config/podio/podio_config.yml +5 -0
- data/config/routes.rb +42 -0
- data/config/symmetric-encryption.yml +107 -0
- data/lib/rxcms-podio_plugin.rb +5 -0
- data/lib/rxcms-podio_plugin/classes/executor.rb +185 -0
- data/lib/rxcms-podio_plugin/engine.rb +12 -0
- data/lib/rxcms-podio_plugin/version.rb +3 -0
- data/lib/tasks/rxcms-podio_plugin_tasks.rake +4 -0
- metadata +133 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
$(function(){
|
2
|
+
$("#submit").on("click", function(){
|
3
|
+
|
4
|
+
if ($("#username").val().length > 0 &&
|
5
|
+
$("#password").val().length > 0 &&
|
6
|
+
$("#podioApiKey").val().length > 0 &&
|
7
|
+
$("#podioSecretKey").val().length > 0)
|
8
|
+
{
|
9
|
+
$.post("/podio/installer/before_process", {
|
10
|
+
'serviceAccountName' : $("#username").val(),
|
11
|
+
'serviceAccountPass' : $("#password").val(),
|
12
|
+
'podioApiKey' : $("#podioApiKey").val(),
|
13
|
+
'podioSecretKey' : $("#podioSecretKey").val()
|
14
|
+
},
|
15
|
+
function(response)
|
16
|
+
{
|
17
|
+
if (response.status == "success")
|
18
|
+
location.reload();
|
19
|
+
else
|
20
|
+
alert("There was an unresolvable problem!");
|
21
|
+
});
|
22
|
+
} else
|
23
|
+
alert("Those fields are required!");
|
24
|
+
|
25
|
+
});
|
26
|
+
});
|
@@ -0,0 +1,98 @@
|
|
1
|
+
class EngineController < ApplicationController
|
2
|
+
include PluginHelper
|
3
|
+
|
4
|
+
layout false
|
5
|
+
|
6
|
+
before_filter :get_current_user_role, :except => [
|
7
|
+
:index
|
8
|
+
]
|
9
|
+
|
10
|
+
before_filter :ensure_login, :only => [ :configure ]
|
11
|
+
|
12
|
+
# Load configuration items (MANDATORY, must be included)
|
13
|
+
APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../../../config/podio/podio_config.yml', __FILE__))))
|
14
|
+
|
15
|
+
# Write your readme here
|
16
|
+
def index
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure
|
21
|
+
if (@curUserRole == 'contentadmin' ||
|
22
|
+
@curUserRole == 'user' ||
|
23
|
+
@curUserRole == 'anonymous' ||
|
24
|
+
@curUserRole == 'loggedin')
|
25
|
+
raise 'unauthorized access'
|
26
|
+
end
|
27
|
+
|
28
|
+
if request.xhr?
|
29
|
+
respond_to do |t|
|
30
|
+
t.html
|
31
|
+
end
|
32
|
+
else
|
33
|
+
raise 'unauthorized access'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def installer
|
38
|
+
if (@curUserRole == 'contentadmin' ||
|
39
|
+
@curUserRole == 'user' ||
|
40
|
+
@curUserRole == 'anonymous' ||
|
41
|
+
@curUserRole == 'loggedin')
|
42
|
+
raise 'unauthorized access'
|
43
|
+
end
|
44
|
+
|
45
|
+
if request.xhr?
|
46
|
+
respond_to do |t|
|
47
|
+
t.html
|
48
|
+
end
|
49
|
+
else
|
50
|
+
raise 'unauthorized access'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
# PODIO plugin
|
57
|
+
def ensure_login
|
58
|
+
if session[:podio_access_token]
|
59
|
+
# Get service user account information from database
|
60
|
+
usrName = Metadata.where("key = ? and sites_id = ?", APP_CONFIG[:SERVICE_ACCOUNT_NAME], session[:accessible_appid]).first
|
61
|
+
usrPass = Metadata.where("key = ? and sites_id = ?", APP_CONFIG[:SERVICE_ACCOUNT_PASS], session[:accessible_appid]).first
|
62
|
+
|
63
|
+
if (!usrName.nil? && !usrPass.nil?)
|
64
|
+
if cookies[:podio].to_s == Digest::SHA2.hexdigest("#{usrName.value.strip}#{usrPass.value.strip}")
|
65
|
+
init_podio_client
|
66
|
+
else
|
67
|
+
redirect_to "/podio/auth/podio_as_user"
|
68
|
+
end
|
69
|
+
else
|
70
|
+
raise "[Err] Since you use podio integration plugin, a service account must be used"
|
71
|
+
end
|
72
|
+
else
|
73
|
+
redirect_to "/podio/auth/podio_as_user"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def init_podio_client
|
78
|
+
apiKey = Metadata.first({:conditions => ["key = ? and sites_id = ?", APP_CONFIG[:PODIO_API_KEY], session[:accessible_appid]]
|
79
|
+
})
|
80
|
+
secretKey = Metadata.first({:conditions => ["key = ? and sites_id = ?", APP_CONFIG[:PODIO_SECRET_KEY], session[:accessible_appid]]
|
81
|
+
})
|
82
|
+
if (!apiKey.nil? && !secretKey.nil?)
|
83
|
+
Podio.setup(
|
84
|
+
:api_url => 'https://api.podio.com',
|
85
|
+
:api_key => apiKey.value.strip,
|
86
|
+
:api_secret => secretKey.value.strip,
|
87
|
+
:oauth_token => Podio::OAuthToken.new('access_token' => session[:podio_access_token], 'refresh_token' => session[:podio_refresh_token])
|
88
|
+
)
|
89
|
+
else
|
90
|
+
# Don't do anything
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
class InstallerController < ApplicationController
|
2
|
+
include PluginHelper
|
3
|
+
|
4
|
+
layout false
|
5
|
+
|
6
|
+
before_filter :get_current_user_role
|
7
|
+
|
8
|
+
# Load configuration items (MANDATORY, must be included)
|
9
|
+
APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../../../config/podio/podio_config.yml', __FILE__))))
|
10
|
+
|
11
|
+
# Each step should return JSON status "success", "failure" or "unimplemented"
|
12
|
+
|
13
|
+
# Used for initializing and creating database entries
|
14
|
+
def before_process
|
15
|
+
begin
|
16
|
+
SymmetricEncryption.load!
|
17
|
+
|
18
|
+
if (@curUserRole == 'contentadmin' ||
|
19
|
+
@curUserRole == 'user' ||
|
20
|
+
@curUserRole == 'anonymous' ||
|
21
|
+
@curUserRole == 'loggedin')
|
22
|
+
raise 'unauthorized access'
|
23
|
+
end
|
24
|
+
|
25
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_NAME], session[:accessible_appid]] }).nil?)
|
26
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_NAME], session[:accessible_appid]] }).destroy
|
27
|
+
end
|
28
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_PASS], session[:accessible_appid]] }).nil?)
|
29
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_PASS], session[:accessible_appid]] }).destroy
|
30
|
+
end
|
31
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_API_KEY], session[:accessible_appid] ]}).nil?)
|
32
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_API_KEY], session[:accessible_appid] ]}).destroy
|
33
|
+
end
|
34
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_SECRET_KEY], session[:accessible_appid]] }).nil?)
|
35
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_SECRET_KEY], session[:accessible_appid]] }).destroy
|
36
|
+
end
|
37
|
+
|
38
|
+
currentWorkspaceMetadata = Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_WORKSPACE], session[:accessible_appid]] })
|
39
|
+
if (!currentWorkspaceMetadata.nil?)
|
40
|
+
currentWorkspaceMetadata.destroy
|
41
|
+
end
|
42
|
+
|
43
|
+
Metadata.create({
|
44
|
+
:key => APP_CONFIG[:SERVICE_ACCOUNT_NAME],
|
45
|
+
:value => params[:serviceAccountName].strip,
|
46
|
+
:cat => 'podio_config',
|
47
|
+
:mime => 'text/plain',
|
48
|
+
:sites_id => session[:accessible_appid]
|
49
|
+
})
|
50
|
+
Metadata.create({
|
51
|
+
:key => APP_CONFIG[:SERVICE_ACCOUNT_PASS],
|
52
|
+
:value => SymmetricEncryption.encrypt(params[:serviceAccountPass].strip),
|
53
|
+
:cat => 'podio_config',
|
54
|
+
:mime => 'text/plain',
|
55
|
+
:sites_id => session[:accessible_appid]
|
56
|
+
})
|
57
|
+
Metadata.create({
|
58
|
+
:key => APP_CONFIG[:PODIO_API_KEY],
|
59
|
+
:value => params[:podioApiKey].strip,
|
60
|
+
:cat => 'podio_config',
|
61
|
+
:mime => 'text/plain',
|
62
|
+
:sites_id => session[:accessible_appid]
|
63
|
+
})
|
64
|
+
Metadata.create({
|
65
|
+
:key => APP_CONFIG[:PODIO_SECRET_KEY],
|
66
|
+
:value => params[:podioSecretKey].strip,
|
67
|
+
:cat => 'podio_config',
|
68
|
+
:mime => 'text/plain',
|
69
|
+
:sites_id => session[:accessible_appid]
|
70
|
+
})
|
71
|
+
|
72
|
+
render :json => { :status => 'success' }
|
73
|
+
rescue
|
74
|
+
render :json => { :status => 'failure' }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Used for logical processing
|
79
|
+
def core_process
|
80
|
+
render :json => { :status => 'unimplemented' }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Used for configuring data
|
84
|
+
def post_process
|
85
|
+
render :json => { :status => 'unimplemented' }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Uninstaller
|
89
|
+
def uninstall
|
90
|
+
begin
|
91
|
+
if (@curUserRole == 'contentadmin' ||
|
92
|
+
@curUserRole == 'user' ||
|
93
|
+
@curUserRole == 'anonymous' ||
|
94
|
+
@curUserRole == 'loggedin')
|
95
|
+
raise 'unauthorized access'
|
96
|
+
end
|
97
|
+
|
98
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_NAME], session[:accessible_appid]] }).nil?)
|
99
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_NAME], session[:accessible_appid]] }).destroy
|
100
|
+
end
|
101
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_PASS], session[:accessible_appid]] }).nil?)
|
102
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:SERVICE_ACCOUNT_PASS], session[:accessible_appid]] }).destroy
|
103
|
+
end
|
104
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_API_KEY], session[:accessible_appid] ]}).nil?)
|
105
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_API_KEY], session[:accessible_appid] ]}).destroy
|
106
|
+
end
|
107
|
+
if (!Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_SECRET_KEY], session[:accessible_appid]] }).nil?)
|
108
|
+
Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_SECRET_KEY], session[:accessible_appid]] }).destroy
|
109
|
+
end
|
110
|
+
|
111
|
+
currentWorkspaceMetadata = Metadata.first({ :conditions => ['key = ? and sites_id = ?', APP_CONFIG[:PODIO_WORKSPACE], session[:accessible_appid]] })
|
112
|
+
if (!currentWorkspaceMetadata.nil?)
|
113
|
+
currentWorkspaceMetadata.destroy
|
114
|
+
end
|
115
|
+
|
116
|
+
render :json => { :status => 'success' }
|
117
|
+
rescue
|
118
|
+
render :json => { :status => 'failure' }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
class PodioController < ApplicationController
|
2
|
+
layout false
|
3
|
+
|
4
|
+
before_filter :ensure_login
|
5
|
+
|
6
|
+
@@abbrErr = "PCR"
|
7
|
+
|
8
|
+
# Get items of apps from podio
|
9
|
+
# Inputs: podio application id, order, limit, offset and fields which have the forms described below
|
10
|
+
# Output: valid json string
|
11
|
+
def get_podio_items
|
12
|
+
|
13
|
+
appid = params[:appid].to_i
|
14
|
+
order = params[:order].nil? ? "ASC" : params[:order].strip # string default = "ASC"
|
15
|
+
limit = params[:limit].nil? ? 30 : params[:limit].to_i # numeric default = 30
|
16
|
+
offset = params[:offset].nil? ? 0 : params[:offset].to_i # numeric default = 0
|
17
|
+
fields = params[:fields].strip # title|money|summary
|
18
|
+
|
19
|
+
appFields = fields.split("|")
|
20
|
+
|
21
|
+
appFieldsArray = Array.new
|
22
|
+
appFields.each do |t|
|
23
|
+
tHash = Hash.new
|
24
|
+
|
25
|
+
tHash[:external_id] = t
|
26
|
+
tHash[:simple] = true
|
27
|
+
|
28
|
+
appFieldsArray << tHash
|
29
|
+
end
|
30
|
+
|
31
|
+
data = nil
|
32
|
+
|
33
|
+
data = get_abstract_items(appFieldsArray, appid, limit, offset, order)
|
34
|
+
|
35
|
+
if (!data.nil?)
|
36
|
+
render :json => {:status => "success", :data => JSON.parse(data.to_json)}
|
37
|
+
else
|
38
|
+
render :json => {:status => "failure"}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_abstract_items(appFieldsArray, appid, limit, offset, order)
|
43
|
+
data = AbstractItem.range(appid, appFieldsArray, {:order => order, :offset => offset, :limit => limit})
|
44
|
+
return data
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get status of podio
|
48
|
+
# Input from GET['appid']
|
49
|
+
# Output json string
|
50
|
+
def get_podio_app_status
|
51
|
+
begin
|
52
|
+
data = params[:appid]
|
53
|
+
app = AbstractApplication.app_exists?(data.to_i)
|
54
|
+
if (app == true)
|
55
|
+
render :json => {:status => "success", :message => "online"}
|
56
|
+
else
|
57
|
+
render :json => {:status => "success", :message => "offline"}
|
58
|
+
end
|
59
|
+
rescue Exception => ex
|
60
|
+
render :json => {:status => "failure", :message => "error"}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get authentication status of podio account
|
65
|
+
# Input from POST['user'], POST['pass']
|
66
|
+
# Output json string
|
67
|
+
def check_user_login
|
68
|
+
podioUser = params[:user]
|
69
|
+
podioPass = params[:pass]
|
70
|
+
status = AbstractApplication.test_authentication?(podioUser, podioPass)
|
71
|
+
|
72
|
+
if (status)
|
73
|
+
render :json => {:status => "success"}
|
74
|
+
else
|
75
|
+
render :json => {:status => "failure"}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Get list of organizations of user
|
80
|
+
# Input
|
81
|
+
# Output
|
82
|
+
def get_list_of_organizations_of_user
|
83
|
+
orgs = AbstractOrganization.get_list_of_organizations
|
84
|
+
|
85
|
+
orgsArray = Array.new
|
86
|
+
orgs.each do |o|
|
87
|
+
tHash = Hash.new
|
88
|
+
tArray = Array.new
|
89
|
+
|
90
|
+
tHash[:id] = defined?(o.id) ? o.id : -1
|
91
|
+
tHash[:name] = o[:name]
|
92
|
+
|
93
|
+
o[:spaces].each do |s|
|
94
|
+
tSpaceHash = Hash.new
|
95
|
+
|
96
|
+
tSpaceHash[:id] = s['space_id']
|
97
|
+
tSpaceHash[:name] = s['name']
|
98
|
+
tArray << tSpaceHash
|
99
|
+
end
|
100
|
+
tHash[:spaces] = tArray
|
101
|
+
|
102
|
+
orgsArray << tHash
|
103
|
+
end
|
104
|
+
|
105
|
+
render :json => orgsArray
|
106
|
+
end
|
107
|
+
|
108
|
+
# Get list of workspaces of user
|
109
|
+
# Input
|
110
|
+
# Output
|
111
|
+
def get_list_of_apps_from_workspace
|
112
|
+
begin
|
113
|
+
spaceid = params[:space]
|
114
|
+
|
115
|
+
appsObj = AbstractApplication.get_apps_list_by_space(spaceid)
|
116
|
+
|
117
|
+
apps = Array.new
|
118
|
+
appsObj.each do |a|
|
119
|
+
tHash = Hash.new
|
120
|
+
tHash['id'] = defined?(a.id) ? a.id : -1
|
121
|
+
tHash['name'] = defined?(a.config) ? a.config['name'] : ''
|
122
|
+
tHash['description'] = defined?(a.config) ? a.config['description'] : ''
|
123
|
+
tHash['icon'] = defined?(a.config) ? a.config['icon'] : ''
|
124
|
+
|
125
|
+
apps << tHash
|
126
|
+
end
|
127
|
+
|
128
|
+
render :json => apps
|
129
|
+
rescue
|
130
|
+
render :json => []
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Get list of apps for elements
|
135
|
+
# Input
|
136
|
+
# Output json string
|
137
|
+
def get_list_of_apps_for_elements
|
138
|
+
# Get all apps
|
139
|
+
curWorkspace = Metadata.find_by_key("currentWorkspace")
|
140
|
+
if (!curWorkspace.nil?)
|
141
|
+
appList = AbstractApplication.get_apps_list_by_space(curWorkspace.value.strip)
|
142
|
+
|
143
|
+
tApps = Metadata.all({:conditions => ['cat = ?', 'app']})
|
144
|
+
|
145
|
+
tAppsArray = Array.new
|
146
|
+
appList.each do |al|
|
147
|
+
tAppsArray << (defined?(al.id) ? al.id.to_s : (-1).to_s)
|
148
|
+
end
|
149
|
+
|
150
|
+
tAppsResult = Array.new
|
151
|
+
tApps.each do |ta|
|
152
|
+
if (tAppsArray.include?(ta.value.strip))
|
153
|
+
tAppsResult << ta
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
apps = tAppsResult
|
158
|
+
else
|
159
|
+
apps = []
|
160
|
+
end
|
161
|
+
|
162
|
+
render :json => apps
|
163
|
+
end
|
164
|
+
|
165
|
+
protected
|
166
|
+
|
167
|
+
# PODIO plugin
|
168
|
+
def ensure_login
|
169
|
+
if session[:podio_access_token]
|
170
|
+
# Get service user account information from database
|
171
|
+
usrName = Metadata.where("key = ?", "serviceAccountName").first
|
172
|
+
usrPass = Metadata.where("key = ?", "serviceAccountPass").first
|
173
|
+
|
174
|
+
if (!usrName.nil? && !usrPass.nil?)
|
175
|
+
if cookies[:podio].to_s == Digest::SHA2.hexdigest("#{usrName.value.strip}#{usrPass.value.strip}")
|
176
|
+
init_podio_client
|
177
|
+
else
|
178
|
+
redirect_to "/podio/auth/podio_as_user"
|
179
|
+
end
|
180
|
+
else
|
181
|
+
raise "Application - #{@@abbrErr}001 Since you use podio integration plugin, a service account must be used"
|
182
|
+
end
|
183
|
+
else
|
184
|
+
redirect_to "/podio/auth/podio_as_user"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def init_podio_client
|
189
|
+
apiKey = Metadata.first({:conditions => ["key = ?", "podioApiKey"]
|
190
|
+
})
|
191
|
+
secretKey = Metadata.first({:conditions => ["key = ?", "podioSecretKey"]
|
192
|
+
})
|
193
|
+
if (!apiKey.nil? && !secretKey.nil?)
|
194
|
+
Podio.setup(
|
195
|
+
:api_url => 'https://api.podio.com',
|
196
|
+
:api_key => apiKey.value.strip,
|
197
|
+
:api_secret => secretKey.value.strip,
|
198
|
+
:oauth_token => Podio::OAuthToken.new('access_token' => session[:podio_access_token], 'refresh_token' => session[:podio_refresh_token])
|
199
|
+
)
|
200
|
+
else
|
201
|
+
# Don't do anything
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|