View | Details | Raw Unified | Return to bug 14723
Collapse All | Expand All

(-)a/C4/Installer/PerlDependencies.pm (+5 lines)
Lines 787-792 our $PERL_DEPS = { Link Here
787
        'required' => '0',
787
        'required' => '0',
788
        'min_ver'  => '0.28',
788
        'min_ver'  => '0.28',
789
    },
789
    },
790
    'LWP::Curl' => {
791
        'usage'    => 'Curl',
792
        'required' => '1',
793
        'min_ver'  => '0.12',
794
    },
790
};
795
};
791
796
792
1;
797
1;
(-)a/C4/SMS.pm (+1 lines)
Lines 87-92 sub send_sms { Link Here
87
        # Send a message
87
        # Send a message
88
        $sent = $sender->send_sms( to   => $params->{'destination'},
88
        $sent = $sender->send_sms( to   => $params->{'destination'},
89
                                  text => $params->{'message'},
89
                                  text => $params->{'message'},
90
                                   message_id => $params->{'message_id'},
90
                             );
91
                             );
91
    };
92
    };
92
    #We might die because SMS::Send $driver is not defined or the sms-number has a bad format
93
    #We might die because SMS::Send $driver is not defined or the sms-number has a bad format
(-)a/Koha/REST/V1/Messages.pm (+39 lines)
Line 0 Link Here
1
package Koha::REST::V1::Messages;
2
3
use Modern::Perl;
4
5
use Mojo::Base 'Mojolicious::Controller';
6
7
use C4::Letters;
8
use Data::Dumper;
9
10
11
=head2 delivery_report($c, $args, $cb)
12
13
SMS provider returns us with a report on state of the SMS delivery.
14
If the delivery is unsuccessful, we will change its status.
15
16
=cut
17
# SMS provider returns us with a report on state of the SMS delivery.
18
# 
19
sub delivery_report {
20
    my ($c, $args, $cb) = @_;
21
22
    if ($args->{status} eq "ERROR") {
23
        C4::Letters::_set_message_status({
24
            status => "failed",
25
            message_id => $args->{messagenumber},
26
            delivery_note => $args->{message}
27
        });
28
    }
29
    
30
    my $return = {
31
        message=> $args->{messagenumber},
32
        status => $args->{status}
33
    };
34
    
35
    $c->$cb($return, 200);
36
    
37
}
38
1;
39
(-)a/SMS/Send/Labyrintti/Driver.pm (+140 lines)
Line 0 Link Here
1
=head IN THIS FILE                                                                                                              
2
     
3
This module extends the SMS::Send::Driver interface                                                                             
4
     
5
to implement a driver compatible with the Labyrintti SMS Gateway HTTP interface.                                                
6
               
7
                                                                                                                                
8
     
9
Module parameters are sanitated against injection attacks.
10
11
Labyrintti responds:
12
13
    success
14
    
15
phone-number OK message-count description
16
+358401234567 OK 1 message accepted for sending
17
18
    failure
19
 
20
phone-number ERROR error-code message-count description
21
e.g: 12345 ERROR 2 1 message failed: Too short phone number
22
     
23
=cut                                                                                                                            
24
     
25
                                                                                                                                
26
     
27
                                                                                                                                
28
     
29
                                                                                                                                
30
     
31
package SMS::Send::Labyrintti::Driver;                                                                                          
32
     
33
                                                                                                                                
34
     
35
#use Modern::Perl; #Can't use this since SMS::Send uses hash keys starting with _                                               
36
     
37
                                                                                                                                
38
     
39
use utf8;                                                                                                                       
40
     
41
                                                                                                                                
42
     
43
use SMS::Send::Driver ();                                                                                                       
44
     
45
use LWP::Curl;
46
use LWP::UserAgent;                                                                                                             
47
     
48
use URI::Escape;
49
use C4::Context;
50
use Encode;
51
52
use vars qw{$VERSION @ISA};
53
BEGIN {
54
        $VERSION = '0.06';
55
                @ISA     = 'SMS::Send::Driver';
56
}
57
58
59
#####################################################################
60
# Constructor
61
62
sub new {
63
        my $class = shift;
64
        my $params = {@_};
65
        my $username = $params->{_login} ? $params->{_login} : C4::Context->config('smsProviders')->{'labyrintti'}->{'user'};
66
        my $password = $params->{_password} ? $params->{_password} : C4::Context->config('smsProviders')->{'labyrintti'}->{'passwd'};
67
        
68
        if (! defined $username ) {
69
            warn "->send_sms(_login) must be defined!";
70
            return;
71
        }
72
        if (! defined $password ) {
73
            warn "->send_sms(_password) must be defined!";
74
            return;
75
        }
76
        
77
        #Prevent injection attack    
78
        $self->{_login} =~ s/'//g;
79
        $self->{_password} =~ s/'//g;
80
        
81
        # Create the object
82
        my $self = bless {}, $class;
83
        
84
        $self->{UserAgent} = LWP::UserAgent->new(timeout => 5);
85
        $self->{_login} = $username;
86
        $self->{_password} = $password;
87
88
        return $self;
89
}
90
91
sub send_sms {
92
    my $self    = shift;
93
    my $params = {@_};
94
    my $message = $params->{text};
95
    my $recipientNumber = $params->{to};
96
    
97
    if (! defined $message ) {
98
        warn "->send_sms(text) must be defined!";
99
        return;
100
    }
101
    if (! defined $recipientNumber ) {
102
        warn "->send_sms(to) must be defined!";
103
        return;
104
    }
105
    
106
    #Prevent injection attack!
107
    $recipientNumber =~ s/'//g;
108
    $message =~ s/(")|(\$\()|(`)/\\"/g; #Sanitate " so it won't break the system( iconv'ed curl command )
109
    
110
    my $base_url = "https://gw.labyrintti.com:28443/sendsms";
111
    my $parameters = {
112
        'user'      => $self->{_login},
113
        'password'  => $self->{_password},
114
        'dests'     => $recipientNumber,
115
        'text'      => $message,
116
        'unicode'   => 'yes',
117
        'report'    => C4::Context->config('smsProviders')->{'labyrintti'}->{'reportUrl'}."/".$params->{_message_id}."/report"
118
    };
119
120
    my $lwpcurl = LWP::Curl->new(auto_encode => 0);
121
    my $return = $lwpcurl->post($base_url, $parameters);
122
123
    
124
    my $delivery_note = $return;
125
    
126
    # remove unneccessary stuff from beginning
127
    if (my $status = ($return =~ m/OK [1-9](\d*)?/)) {
128
        $delivery_note =~ "";
129
    } else {
130
        $delivery_note =~ s/^(\S+\s*){4}//;
131
    }
132
    
133
    return {
134
        status => $status,
135
        delivery_note => $delivery_note,
136
    };
137
}
138
    
139
1;
140
(-)a/api/v1/swagger.json (-1 / +68 lines)
Lines 78-83 Link Here
78
        ]
78
        ]
79
      }
79
      }
80
    }
80
    }
81
    "/messages/{messagenumber}/report": {
82
      "post": {
83
        "x-mojo-controller": "Koha::REST::V1::Messages",
84
        "operationId": "deliveryReport",
85
        "tags": ["messages"],
86
        "parameters": [
87
          {
88
            "$ref": "#/parameters/messagenumberPathParam"
89
          },
90
          {
91
            "$ref": "#/parameters/messageStatusFormParam"
92
          },
93
          {
94
            "$ref": "#/parameters/messageDeliveryNoteFormParam"
95
          }
96
        ],
97
        "produces": [
98
          "application/json"
99
        ],
100
        "responses": {
101
          "200": {
102
            "description": "Response for receiving report",
103
            "schema": {
104
              "$ref": "#/definitions/messageStatus"
105
            }
106
          },
107
          "404": {
108
            "description": "Message not found",
109
            "schema": {
110
              "$ref": "#/definitions/error"
111
            }
112
          }
113
        }
114
      }
115
    },
81
  },
116
  },
82
  "definitions": {
117
  "definitions": {
83
    "borrower": {
118
    "borrower": {
Lines 108-114 Link Here
108
          "type": "string"
143
          "type": "string"
109
        }
144
        }
110
      }
145
      }
111
    }
146
    },
147
    "messageStatus": {
148
      "type": "object",
149
      "properties": {
150
        "message": {
151
          "description": "Message identification number"
152
        },
153
        "status": {
154
          "description": "Message delivery status"
155
        }
156
      }
157
    },
112
  },
158
  },
113
  "parameters": {
159
  "parameters": {
114
    "borrowernumberPathParam": {
160
    "borrowernumberPathParam": {
Lines 117-122 Link Here
117
      "description": "Internal borrower identifier",
163
      "description": "Internal borrower identifier",
118
      "required": "true",
164
      "required": "true",
119
      "type": "integer"
165
      "type": "integer"
166
    },
167
    "messagenumberPathParam": {
168
      "name": "messagenumber",
169
      "in": "path",
170
      "description": "Internal message number",
171
      "required": "true",
172
      "type": "integer"
173
    },
174
    "messageStatusFormParam": {
175
      "name": "status",
176
      "in": "formData",
177
      "description": "Status of message delivery",
178
      "required": "true",
179
      "type": "string"
180
    },
181
    "messageDeliveryNoteFormParam": {
182
      "name": "message",
183
      "in": "formData",
184
      "description": "Description of message delivery status",
185
      "required": "true",
186
      "type": "string"
120
    }
187
    }
121
  },
188
  },
122
  "securityDefinitions": {
189
  "securityDefinitions": {
(-)a/etc/koha-conf.xml (+12 lines)
Lines 145-149 __PAZPAR2_TOGGLE_XML_POST__ Link Here
145
    </rest>
145
    </rest>
146
 </testservers>
146
 </testservers>
147
147
148
 <smsProviders>
149
    <labyrintti>
150
        <!-- Login details for SMS Gateway service --> 
151
        <user></user>
152
        <passwd></passwd>
153
        <!-- Report URL is the page where your SMS Gateway provider will send a report
154
             about the delivery of the message.
155
156
             With REST API, it should be http://mydomain.com/v1/messages -->
157
        <reportUrl></reportUrl>
158
    </labyrintti>
159
 </smsProviders>
148
</config>
160
</config>
149
</yazgfs>
161
</yazgfs>
(-)a/etc/koha-httpd.conf (-1 / +9 lines)
Lines 39-44 Link Here
39
   ProxyPassReverse /v1/  http://localhost:8081/v1/
39
   ProxyPassReverse /v1/  http://localhost:8081/v1/
40
   ##REVERSE PROXYING OK
40
   ##REVERSE PROXYING OK
41
41
42
# Uncomment the following block to restrict access for changing
43
# message status via reports to only from certain IPs.
44
#   <LocationMatch "/v1/messages/\d+/report$">
45
#      Order Deny,Allow
46
#      Deny from all
47
#      Allow from 101.123.213.10
48
#      Allow from 101.123.213.11
49
#   </LocationMatch>
50
42
   <Directory "__OPAC_WWW_DIR__">
51
   <Directory "__OPAC_WWW_DIR__">
43
      Options -Indexes
52
      Options -Indexes
44
   </Directory>
53
   </Directory>
45
- 

Return to bug 14723