PluginProbe
FV Player 8 / trunk
FV Player 8 vtrunk
trunk 8.0.18 8.0.19 8.0.20 8.0.21 8.0.25 8.0.27 8.1 8.1.3
fv-player / models / digitalocean-spaces.class.php

digitalocean-spaces.class.php in FV Player 8 trunk, at models/digitalocean-spaces.class.php

248 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 if( !class_exists('FV_Player_DigitalOcean_Spaces') ) :
8
9 class FV_Player_DigitalOcean_Spaces extends FV_Player_CDN {
10
11 function __construct() {
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 // TODO: What if FV Player is not yet loaded?
18 parent::__construct( array( 'key' => 'digitalocean_spaces', 'title' => 'DigitalOcean Spaces') );
19
20 // we use priority of 9 to make sure it's loaded before FV Player Pro would load it
21 add_action( 'plugins_loaded', array( $this, 'include_dos_media_browser' ), 9 );
22 add_action( 'admin_init', array( $this, 'remove_fv_player_pro_dos' ), 21 );
23 add_action( 'admin_init', array( $this, 'migrate_fv_player_pro_dos' ), 21 );
24 }
25
26 // includes the Digital Ocean Spaces handling class itself
27 public function include_dos_media_browser() {
28 if ( is_admin() && version_compare(phpversion(),'7.4') != -1 ) {
29 include( dirname( __FILE__ ) . '/digitalocean-spaces-browser.class.php' );
30 }
31 }
32
33 function get_endpoint() {
34 global $fv_fp;
35 $parsed = wp_parse_url( $fv_fp->_get_option( array($this->key,'endpoint' ) ) );
36
37 if( count($parsed) == 1 && !empty($parsed['path']) ) { // for input like "region.digitaloceanspaces.com" it returns it as path, not realizing it's the hostname
38 return $parsed['path'];
39
40 } else if( !empty($parsed['host']) ) {
41 return $parsed['host'];
42
43 }
44 return false;
45 }
46
47 function get_space() {
48 global $fv_fp;
49 $space = $fv_fp->_get_option( array($this->key,'space' ) );
50
51 // If multiple DigitalOcean Spaces are configured, use the first one
52 $spaces = explode( ',', $space );
53 $space = $spaces[0];
54
55 return $space;
56 }
57
58 function get_domains() {
59 global $fv_fp;
60 $spaces = $fv_fp->_get_option( array($this->key,'space' ) );
61 $spaces = explode( ',', $spaces );
62
63 $endpoint = $this->get_endpoint();
64
65 $domains = array();
66
67 foreach ( $spaces as $space ) {
68 if( $space && $endpoint ) {
69 /**
70 * TODO: These two domains are really a problem. We do not store the endpoint for each Space, so here we just assume any.
71 * It's used in case of redundant Spaces which are not properly defined yet.
72 */
73 $domains[] = $space . '.';
74 $domains[] = '/' . $space;
75
76 $domains[] = $space . '.' . $endpoint;
77 $domains[] = $endpoint . '/' . $space;
78 }
79 }
80
81 if ( count( $domains ) ) {
82 return $domains;
83 } else {
84 return false;
85 }
86 }
87
88 function get_region() {
89 $parts = explode( '.', $this->get_endpoint() );
90 return $parts[0];
91 }
92
93 function get_secure_tokens() {
94 global $fv_fp;
95 return array( $fv_fp->_get_option( array($this->key,'secret' ) ) );
96 }
97
98 /*
99 * Migrate DigitalOcean Spaces settings from FV Player Pro
100 */
101 function migrate_fv_player_pro_dos() {
102 $option = get_option('fvwpflowplayer');
103
104 $found_anything = false;
105
106 global $fv_fp;
107 foreach( array(
108 'endpoint',
109 'secret',
110 'key',
111 'space'
112 ) AS $key ) {
113
114 // bail if we have something already
115 if( !empty($option['digitalocean_spaces']) && !empty($option['digitalocean_spaces'][$key]) ) continue;
116
117 if( $value = $fv_fp->_get_option( array( 'pro', 'digitalocean_spaces_'.$key ) ) ) {
118 if( empty($option['digitalocean_spaces']) ) $option['digitalocean_spaces'] = array();
119
120 $option['digitalocean_spaces'][$key] = $value;
121
122 $found_anything = true;
123 }
124 }
125
126 if( $found_anything ) {
127 update_option('fvwpflowplayer', $option);
128 }
129
130 }
131
132 function options() {
133 // TODO: Fix width
134 // TODO: Add custom domain for CDN
135 global $fv_fp;
136 ?>
137 <table class="form-table2" style="margin: 5px; ">
138 <?php
139 $fv_fp->_get_input_text( array(
140 'key' => array($this->key,'space'),
141 'name' => 'Space Name',
142 'first_td_class' => 'first'
143 ) );
144 $fv_fp->_get_input_text( array(
145 'key' => array($this->key,'endpoint'),
146 'name' => 'Endpoint'
147 ) );
148 $fv_fp->_get_input_text( array(
149 'key' => array($this->key,'key'),
150 'name' => 'Key'
151 ) );
152 $fv_fp->_get_input_text( array(
153 'key' => array($this->key,'secret'),
154 'name' => 'Secret',
155 'secret' => true
156 ) );
157 ?>
158 <tr>
159 <td colspan="4">
160 <a class="fv-wordpress-flowplayer-save button button-primary" href="#" style="margin-top: 2ex;"><?php esc_html_e( 'Save', 'fv-player' ); ?></a>
161 </td>
162 </tr>
163 </table>
164 <?php
165 }
166
167 function remove_fv_player_pro_dos() {
168 // remove the legacy settings box in FV Player Pro
169 remove_meta_box('fv_player_pro_digitalocean_spaces', 'fv_flowplayer_settings_hosting', 'normal');
170 }
171
172 function secure_link( $url, $secret, $ttl = false ) {
173
174 if( stripos($url,'X-Amz-Expires') !== false ) return $url;
175
176 global $fv_fp;
177 $key = $fv_fp->_get_option( array($this->key,'key' ) );
178 $secret = $fv_fp->_get_option( array($this->key,'secret' ) );
179 $endpoint = $fv_fp->_get_option( array($this->key,'endpoint' ) );
180 $endpoint = explode('.',$endpoint);
181 $endpoint = $endpoint[0];
182
183 $time = $ttl ? $ttl : apply_filters('fv_player_secure_link_timeout', 900);
184
185 $url_components = wp_parse_url($url);
186
187 $url_components['path'] = str_replace( array('%20','+'), ' ', $url_components['path']);
188
189 $url_components['path'] = rawurlencode($url_components['path']);
190 $url_components['path'] = str_replace('%2F', '/', $url_components['path']);
191 $url_components['path'] = str_replace('%2B', '+', $url_components['path']);
192 $url_components['path'] = str_replace('%2523', '%23', $url_components['path']);
193 $url_components['path'] = str_replace('%252B', '%2B', $url_components['path']);
194 $url_components['path'] = str_replace('%2527', '%27', $url_components['path']);
195
196 // Round the current time to the nearest $time interval to ensure consistent signatures
197 // Use ceil() to ensure URLs are valid for the full $time duration
198 $currentTime = time();
199 $roundedTime = ceil($currentTime / $time) * $time;
200
201 $sXAMZDate = gmdate('Ymd\THis\Z', $roundedTime);
202 $sDate = gmdate('Ymd', $roundedTime);
203 $sCredentialScope = $sDate."/".$endpoint."/s3/aws4_request"; // todo: variable
204 $sSignedHeaders = "host";
205 $sXAMZCredential = urlencode( $key.'/'.$sCredentialScope);
206
207 // Support DigitalOcean Spaces CDN
208 $url_components['host'] = str_replace( 'cdn.', '', $url_components['host'] );
209
210 // 1. http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
211 $sCanonicalRequest = "GET\n";
212 $sCanonicalRequest .= $url_components['path']."\n";
213 $sCanonicalRequest .= "X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=$sXAMZCredential&X-Amz-Date=$sXAMZDate&X-Amz-Expires=$time&X-Amz-SignedHeaders=$sSignedHeaders\n";
214 $sCanonicalRequest .= "host:".$url_components['host']."\n";
215 $sCanonicalRequest .= "\n$sSignedHeaders\n";
216 $sCanonicalRequest .= "UNSIGNED-PAYLOAD";
217
218 // 2. http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
219 $sStringToSign = "AWS4-HMAC-SHA256\n";
220 $sStringToSign .= "$sXAMZDate\n";
221 $sStringToSign .= "$sCredentialScope\n";
222 $sStringToSign .= hash('sha256',$sCanonicalRequest);
223
224 // 3. http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
225 $sSignature = hash_hmac('sha256', $sDate, "AWS4".$secret, true );
226 $sSignature = hash_hmac('sha256', $endpoint, $sSignature, true ); // todo: variable
227 $sSignature = hash_hmac('sha256', 's3', $sSignature, true );
228 $sSignature = hash_hmac('sha256', 'aws4_request', $sSignature, true );
229 $sSignature = hash_hmac('sha256', $sStringToSign, $sSignature );
230
231 // 4. http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
232 $url .= "?X-Amz-Algorithm=AWS4-HMAC-SHA256";
233 $url .= "&X-Amz-Credential=$sXAMZCredential";
234 $url .= "&X-Amz-Date=$sXAMZDate";
235 $url .= "&X-Amz-Expires=$time";
236 $url .= "&X-Amz-SignedHeaders=$sSignedHeaders";
237 $url .= "&X-Amz-Signature=".$sSignature;
238
239 return $url;
240 }
241
242 }
243
244 global $FV_Player_DigitalOcean_Spaces;
245 $FV_Player_DigitalOcean_Spaces = new FV_Player_DigitalOcean_Spaces;
246
247 endif;
248