1
+ require 'net/http'
2
+
1
3
class SubscriptionTemplatesController < ApplicationController
2
4
layout 'base'
3
5
4
6
before_action :find_project_by_project_id , except : [ :index , :set_subscription_id ]
5
7
before_action :get_issue_statuses , only : [ :new , :create , :edit , :update ]
6
8
before_action :get_issue_priorities , only : [ :new , :create , :edit , :update ]
7
9
before_action :get_issue_categories , only : [ :new , :create , :edit , :update ]
10
+ before_action :find_subscription_template , only : [ :edit , :update , :destroy , :copy , :publish , :unpublish , :update_subscription_id ]
11
+ before_action :check_fiware_broker_auth_token , only : [ :publish , :unpublish ]
8
12
9
13
accept_api_auth :set_subscription_id
10
14
before_action :authorize , except : [ :set_subscription_id ]
@@ -19,9 +23,7 @@ def new
19
23
@subscription_template = SubscriptionTemplate . new
20
24
end
21
25
22
- def edit
23
- @subscription_template = find_subscription_template
24
- end
26
+ def edit ; end
25
27
26
28
def create
27
29
r = RedmineGttFiware ::SaveSubscriptionTemplate . ( subscription_template_params , project : @project )
@@ -34,8 +36,6 @@ def create
34
36
end
35
37
36
38
def update
37
- @subscription_template = find_subscription_template
38
-
39
39
r = RedmineGttFiware ::SaveSubscriptionTemplate . ( subscription_template_params , subscription_template : @subscription_template )
40
40
if r . subscription_template_saved?
41
41
redirect_to index_path
@@ -55,15 +55,13 @@ def update_subscription_id
55
55
end
56
56
57
57
def set_subscription_id
58
- # Check if a valid API key is provided
59
58
unless User . current . logged?
60
59
render json : { error : 'API key is missing or invalid' } , status : :unauthorized
61
60
return
62
61
end
63
62
64
63
@subscription_template = SubscriptionTemplate . find ( params [ :subscription_template_id ] )
65
64
66
- # Check if the user has permissions to manage subscription templates
67
65
unless User . current . allowed_to? ( :manage_subscription_templates , @subscription_template . project )
68
66
render json : { error : 'You do not have permission to manage subscription templates' } , status : :forbidden
69
67
return
@@ -75,7 +73,6 @@ def set_subscription_id
75
73
end
76
74
77
75
def destroy
78
- @subscription_template = find_subscription_template
79
76
@subscription_template . destroy
80
77
redirect_to index_path
81
78
end
@@ -89,36 +86,53 @@ def copy
89
86
end
90
87
91
88
def publish
92
- prepare_payload
93
-
94
- respond_to do |format |
95
- format . js # This will render `publish.js.erb`
96
- end
89
+ handle_publish_unpublish ( 'publish' , l ( :subscription_published ) , 'publish.js.erb' )
97
90
end
98
91
99
92
def unpublish
100
- @subscription_template = SubscriptionTemplate . find ( params [ :id ] )
101
93
@broker_url = URI . join ( @subscription_template . broker_url , "/v2/subscriptions/" , @subscription_template . subscription_id ) . to_s
94
+ handle_publish_unpublish ( 'unpublish' , l ( :subscription_unpublished ) , 'unpublish.js.erb' )
95
+ end
102
96
103
- respond_to do |format |
104
- format . js # This will render `unpublish.js.erb`
97
+ private
98
+
99
+ def handle_publish_unpublish ( action , success_message , js_template )
100
+ prepare_payload if action == 'publish'
101
+
102
+ if Setting . plugin_redmine_gtt_fiware [ 'connect_via_proxy' ]
103
+ if handle_fiware_action ( action )
104
+ render_subscription_templates ( success_message )
105
+ else
106
+ render_subscription_templates ( @error_message )
107
+ end
108
+ else
109
+ respond_to do |format |
110
+ format . js { render js_template }
111
+ end
105
112
end
106
113
end
107
114
108
- private
115
+ def render_subscription_templates ( message )
116
+ @subscription_templates = subscription_template_scope
117
+ respond_to do |format |
118
+ format . html {
119
+ response . headers [ 'X-Redmine-Message' ] = message
120
+ render partial : 'subscription_templates/subscription_template' , collection : @subscription_templates , as : :subscription_template
121
+ }
122
+ end
123
+ end
109
124
110
125
def prepare_payload
111
- @subscription_template = SubscriptionTemplate . find ( params [ :id ] )
112
126
@broker_url = URI . join ( @subscription_template . broker_url , "/v2/subscriptions" ) . to_s
113
127
@entity_url = URI . join ( @subscription_template . broker_url , "/v2/entities" ) . to_s
114
128
@member = Member . find ( @subscription_template . member_id )
115
129
116
- httpCustom = {
130
+ http_custom = {
117
131
url : URI . join ( request . base_url , "/fiware/subscription_template/#{ @subscription_template . id } /notification" ) . to_s ,
118
132
headers : {
119
- "Content-Type" : "application/json" ,
120
- "X-Redmine-API-Key" : User . find ( @member . user_id ) . api_key ,
121
- "X-Redmine-GTT-Subscription-Template-URL" : URI . join ( request . base_url , "/fiware/subscription_template/#{ @subscription_template . id } /registration/" ) . to_s
133
+ "Content-Type" => "application/json" ,
134
+ "X-Redmine-API-Key" => User . find ( @member . user_id ) . api_key ,
135
+ "X-Redmine-GTT-Subscription-Template-URL" => URI . join ( request . base_url , "/fiware/subscription_template/#{ @subscription_template . id } /registration/" ) . to_s
122
136
} ,
123
137
method : "POST" ,
124
138
json : {
@@ -131,10 +145,8 @@ def prepare_payload
131
145
}
132
146
}
133
147
134
- httpCustom [ :json ] [ :attachments ] = @subscription_template . attachments if @subscription_template . attachments
135
-
136
148
@json_payload = {
137
- description : CGI :: escape ( @subscription_template . name ) ,
149
+ description : CGI . escape ( @subscription_template . name ) ,
138
150
subject : {
139
151
entities : @subscription_template . entities ,
140
152
condition : {
@@ -146,7 +158,7 @@ def prepare_payload
146
158
metadata : [ "dateCreated" , "*" ] ,
147
159
onlyChangedAttrs : false ,
148
160
covered : false ,
149
- httpCustom : httpCustom
161
+ httpCustom : http_custom
150
162
} ,
151
163
throttling : Setting . plugin_redmine_gtt_fiware [ 'fiware_broker_subscription_throttling' ] . to_i || 1 ,
152
164
status : @subscription_template . status
@@ -169,14 +181,7 @@ def prepare_payload
169
181
@json_payload [ :subject ] [ :condition ] [ :attrs ] = JSON . parse ( @subscription_template . attrs ) if @subscription_template . attrs . present?
170
182
@json_payload [ :subject ] [ :condition ] [ :alterationTypes ] = @subscription_template . alteration_types if @subscription_template . alteration_types . present?
171
183
172
- @json_payload = JSON . pretty_generate ( @json_payload )
173
- . gsub ( "\\ " , "\\ \\ \\ \\ " ) # escape backslashes
174
- . gsub ( "\r " , "\\ r" ) # escape carriage return
175
- . gsub ( "\n " , "\\ n" ) # escape newline
176
- . gsub ( "\t " , "\\ t" ) # escape tab
177
- . gsub ( "\f " , "\\ f" ) # escape form feed
178
- . gsub ( "\b " , "\\ b" ) # escape backspace
179
- . gsub ( "\" " , "\\ \" " ) # escape double quotes
184
+ @json_payload = JSON . generate ( @json_payload )
180
185
end
181
186
182
187
def new_path
@@ -188,11 +193,11 @@ def index_path
188
193
end
189
194
190
195
def find_subscription_template
191
- subscription_template_scope . find params [ :id ]
196
+ @subscription_template = subscription_template_scope . find ( params [ :id ] )
192
197
end
193
198
194
199
def find_project_by_project_id
195
- @project = Project . find params [ :project_id ]
200
+ @project = Project . find ( params [ :project_id ] )
196
201
end
197
202
198
203
def subscription_template_scope
@@ -216,4 +221,71 @@ def subscription_template_params
216
221
params . require ( :subscription_template ) . permit ( :standard , :broker_url , :fiware_service , :fiware_servicepath , :subscription_id , :name , :expires , :status , :context , :entities_string , :attrs , :expression_query , :expression_georel , :expression_geometry , :expression_coords , :notify_on_metadata_change , :subject , :description , :attachments_string , :is_private , :project_id , :tracker_id , :version_id , :issue_status_id , :issue_category_id , :issue_priority_id , :member_id , :comment , :threshold_create , :threshold_create_hours , :notes , :geometry , :geometry_string , alteration_types : [ ] )
217
222
end
218
223
224
+ def check_fiware_broker_auth_token
225
+ @fiware_broker_auth_token = request . headers [ 'HTTP_FIWARE_BROKER_AUTH_TOKEN' ]
226
+ end
227
+
228
+ def handle_fiware_action ( action )
229
+
230
+ if @fiware_broker_auth_token . blank?
231
+ Rails . logger . error "FIWARE Broker Auth Token is missing"
232
+ @error_message = l ( :subscription_unauthorized_error )
233
+ return false
234
+ end
235
+
236
+ uri = URI ( @broker_url )
237
+ http = Net ::HTTP . new ( uri . host , uri . port )
238
+ http . use_ssl = ( uri . scheme == 'https' )
239
+
240
+ request = case action
241
+ when 'publish'
242
+ Net ::HTTP ::Post . new ( uri . path , initheader = {
243
+ 'Content-Type' => 'application/json' ,
244
+ 'Authorization' => "Bearer #{ @fiware_broker_auth_token } "
245
+ } ) . tap { |req | req . body = @json_payload }
246
+ when 'unpublish'
247
+ Net ::HTTP ::Delete . new ( uri . path , initheader = {
248
+ 'Authorization' => "Bearer #{ @fiware_broker_auth_token } "
249
+ } )
250
+ else
251
+ Rails . logger . error "Unknown action: #{ action } "
252
+ @error_message = l ( :general_action_error )
253
+ return false
254
+ end
255
+
256
+ response = http . request ( request )
257
+
258
+ Rails . logger . info "FIWARE Broker Response Code: #{ response . code } "
259
+ Rails . logger . info "FIWARE Broker Response Message: #{ response . message } "
260
+
261
+ if response . code . to_i == 201 && action == 'publish'
262
+ location_header = response [ 'location' ] || response [ 'Location' ]
263
+ if location_header
264
+ subscription_id = location_header . split ( '/' ) . last
265
+ @subscription_template . update ( subscription_id : subscription_id )
266
+ return true
267
+ else
268
+ Rails . logger . error "Location header is missing in the response"
269
+ @error_message = l ( :general_action_error )
270
+ return false
271
+ end
272
+ elsif response . code . to_i == 204 && action == 'unpublish'
273
+ @subscription_template . update ( subscription_id : nil )
274
+ return true
275
+ end
276
+
277
+ if response . code . to_i >= 400
278
+ Rails . logger . error "FIWARE Broker error: #{ response . body } "
279
+ @error_message = l ( :general_action_error )
280
+ false
281
+ else
282
+ true
283
+ end
284
+ rescue StandardError => e
285
+ Rails . logger . error "Error handling FIWARE action: #{ e . message } "
286
+ Rails . logger . error e . backtrace . join ( "\n " )
287
+ @error_message = l ( :general_action_error )
288
+ false
289
+ end
290
+
219
291
end
0 commit comments