Merge lp:~gesha/linaro-license-protection/build-info-support into lp:~linaro-automation/linaro-license-protection/trunk
- build-info-support
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Stevan Radaković |
Approved revision: | 95 |
Merged at revision: | 78 |
Proposed branch: | lp:~gesha/linaro-license-protection/build-info-support |
Merge into: | lp:~linaro-automation/linaro-license-protection/trunk |
Diff against target: |
724 lines (+560/-39) 12 files modified
.htaccess (+4/-3) android/build-info/BUILD-INFO.txt (+38/-0) android/build-info/origen-blob.txt (+1/-0) android/build-info/panda-open.txt (+1/-0) android/build-info/snowball-blob.txt (+1/-0) licenses/BuildInfo.php (+168/-0) licenses/license.php (+58/-34) tests/BUILD-INFO.txt (+18/-0) tests/BuildInfoTest.php (+244/-0) tests/LicenseHelperTest.php (+1/-1) tests/test_click_through_license.py (+25/-0) tests/test_php_unit.py (+1/-1) |
To merge this branch: | bzr merge lp:~gesha/linaro-license-protection/build-info-support |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stevan Radaković | Approve | ||
Данило Шеган | Pending | ||
Review via email: mp+107599@code.launchpad.net |
Commit message
Description of the change
This branch adds support for BUILD-INFO.txt license protection.
BUILD-INFO.txt describes files to be protected, the license type, it contains license text. For the first step Version info, Build name, OpenID protection and User info collection are not used.
If the BUILD-INFO.txt is absent then previous EULA/OPEN-EULA protection is used.
- 85. By Georgy Redkozubov
-
Added missing files
- 86. By Georgy Redkozubov
-
[merge] Fix php unit wrong error message when tests are failing.
Stevan Radaković (stevanr) wrote : | # |
- 87. By Georgy Redkozubov
-
Fixed 'Files-Pattern' with multiple patterns
- 88. By Georgy Redkozubov
-
Added cunstructor and updated code to take into account it
- 89. By Georgy Redkozubov
-
Merged PHP unit tests into single test class
- 90. By Georgy Redkozubov
-
Added comments to code
- 91. By Georgy Redkozubov
-
Added tests for testing contents of BUILD-INFO array
- 92. By Georgy Redkozubov
-
Fixed indentation
Georgy Redkozubov (gesha) wrote : | # |
> Nice work gesha.
> I have one general proposal: The license text should be extracted from
> the build info file and put in the separate file in the same directory
> as the build info file.
We've agreed to have a license text inside of the BUILD-INFO.txt when made discussed the format of that file.
>
> Few comments on the code also:
>
> > + public function readFile($fn)
> > + {
> > + $this->search_path = dirname($fn);
> > + $field = '';
> > + $fp_read = 0;
> > + if (is_dir($fn) or !is_file($fn) or filesize($fn) == 0) return
> false; is
> > + $file = fopen($fn, "r") or exit("Unable to open file $fn!");
>
> There are exceptions in PHP as well, I started using them in the project
> so I think it should be good idea that we stick with that.
Actually it is usual to open files such way. There is no suitable exception for that.
> > + $this->
> > + $fp_read = 0;
> > + }
> > + $line = fgets($file);
> > + if (trim($line) == "")
> > + continue;
> > + $fields = explode(":", $line, "2");
> > + if ($fields[0] == "Files-Pattern") {
> > + $tmp_arr = array();
> > + $fp = trim($fields[1]);
> > + while(!feof($file)) {
> > + $line = fgets($file);
> > + if (trim($line) == "")
> > + continue;
> > + $fields = explode(":", $line, "2");
> > + if (in_array(
> > + $field = $fields[0];
> > + if (isset($fields[1]))
> > + $tmp_arr[
> > + while(!feof($file)) {
> > + $line = fgets($file);
> > + if (trim($line) == "")
> > + continue;
> > + $fields = explode(":", $line, "2");
> > + if(in_array(
> {
> > + if ($fields[0] == "Files-Pattern") {
> > + fseek($file, -(strlen($line)),
> SEEK_CUR);
> > + break 2;
> > + }
> > + break;
> > + }
> > + $tmp_arr[$field] = $tmp_arr[$field].
> > + "\n".rtrim($line);
> > + }
> > +
> > + }
> > + if (isset($fields[1])) {
> > + $tmp_arr[
> > + }
> > + }
> > + $this->
> > + unset($tmp_arr);
> > + }
> > + }
> > + fclose($file);
> > +
> > + return true;
> > + }
> > +
>
> First, the code above is not commented at all and was very hard to read.
> I think this will change anyway if you apply the license text ext...
Georgy Redkozubov (gesha) wrote : | # |
Refactored BUILD-INFO.txt parsing.
Updated tests.
- 93. By Georgy Redkozubov
-
[merge] Danilos TDD intro
- 94. By Georgy Redkozubov
-
Refactored parsing BUILD-INFO.txt
Stevan Radaković (stevanr) wrote : | # |
Hi gesha,
Your additions look great!
Few small pointers tho:
92 === added file 'licenses/
93 --- licenses/
94 +++ licenses/
95 @@ -0,0 +1,207 @@
96 +<?php
97 +
98 +class BuildInfo
99 +{
100 + private $text_array = array();
101 + private $fields_defined = array("
102 + "Build-Name", "Theme", "License-Type", "OpenID-
103 + "Collect-
104 + private $multiline_vars = array("
105 + private $search_path = '';
106 + private $fname = '';
I would really like to see all the initialization inside the __construct class.
Furthermore, empty strings need not be initialized. "private $fname;" is enough.
There are very small amount of comments in the BuildInfo.php file.
Fields like text_array are very non-descriptive, we should rename those as well.
132 + private function getInfoForFile(
133 + {
134 + /**
135 + * Get array of fields for corresponding file
136 + */
137 + foreach (array_
138 + if ($key != 'Format-Version') {
139 + $files = glob($this-
140 + foreach ($files as $file)
141 + if ($file == $this->
142 + return $this->
143 + }
144 + return array();
145 + }
We can avoid this whole mumbo by putting $fname as the attribute of the class and then only hold the relevant build info data for that file in text_array attribute. That's all we need for each HTTP request anyway.
165 + public function getTheme($fname)
166 + {
167 + $info = $this->
168 + if (array_
169 + return $info["Theme"];
170 + else
171 + return false;
172 + }
All getFieldX methods should be united in one method.
I.e. public function get($fieldName) - (if we remove $fname as suggested above)
We'll get less code, less tests, and if we would need to implement new fields, we wouldn't need to add separate method and additional tests.
801 === modified file 'tests/
802 --- tests/test_
803 +++ tests/test_
804 @@ -36,6 +36,9 @@
Tests fail for these 3 new tests added..
- 95. By Georgy Redkozubov
-
Refactored 'getX' methods into single 'get' method. Updated code to use new approach.
Georgy Redkozubov (gesha) wrote : | # |
Stevan, thanks for review. Your notes are good.
>
>
> I would really like to see all the initialization inside the __construct
> class.
> Furthermore, empty strings need not be initialized. "private $fname;" is
> enough.
>
> There are very small amount of comments in the BuildInfo.php file.
> Fields like text_array are very non-descriptive, we should rename those as
> well.
Moved inititalization to constructor.
>
> We can avoid this whole mumbo by putting $fname as the attribute of the class
> and then only hold the relevant build info data for that file in text_array
> attribute. That's all we need for each HTTP request anyway.
That's a good point.
>
>
> All getFieldX methods should be united in one method.
> I.e. public function get($fieldName) - (if we remove $fname as suggested
> above)
> We'll get less code, less tests, and if we would need to implement new fields,
> we wouldn't need to add separate method and additional tests.
>
I refactored code and did the reduction.
>
> 801 === modified file 'tests/
> 802 --- tests/test_
> 803 +++ tests/test_
> 804 @@ -36,6 +36,9 @@
>
> Tests fail for these 3 new tests added..
That was by the mistype. Fixed.
Stevan Radaković (stevanr) wrote : | # |
Great work gesha. Approved.
> Stevan, thanks for review. Your notes are good.
>
> >
> >
> > I would really like to see all the initialization inside the __construct
> > class.
> > Furthermore, empty strings need not be initialized. "private $fname;" is
> > enough.
> >
> > There are very small amount of comments in the BuildInfo.php file.
> > Fields like text_array are very non-descriptive, we should rename those as
> > well.
>
> Moved inititalization to constructor.
>
> >
> > We can avoid this whole mumbo by putting $fname as the attribute of the
> class
> > and then only hold the relevant build info data for that file in text_array
> > attribute. That's all we need for each HTTP request anyway.
>
> That's a good point.
>
> >
> >
> > All getFieldX methods should be united in one method.
> > I.e. public function get($fieldName) - (if we remove $fname as suggested
> > above)
> > We'll get less code, less tests, and if we would need to implement new
> fields,
> > we wouldn't need to add separate method and additional tests.
> >
>
> I refactored code and did the reduction.
>
> >
> > 801 === modified file 'tests/
> > 802 --- tests/test_
> > 803 +++ tests/test_
> > 804 @@ -36,6 +36,9 @@
> >
> > Tests fail for these 3 new tests added..
>
> That was by the mistype. Fixed.
Preview Diff
1 | === modified file '.htaccess' |
2 | --- .htaccess 2012-05-11 12:03:32 +0000 |
3 | +++ .htaccess 2012-06-11 10:48:21 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -IndexIgnore HEADER* licenses *EULA* |
6 | +IndexIgnore HEADER* licenses *EULA* BUILD-INFO.txt |
7 | IndexOptions FancyIndexing HTMLTable |
8 | |
9 | RewriteEngine On |
10 | @@ -93,13 +93,14 @@ |
11 | RewriteCond %{HTTP_COOKIE} redirectlicensephp=404 |
12 | RewriteRule .* - [CO=redirectlicensephp:INVALID:.%{ENV:CO_DOMAIN}:-1,L] |
13 | |
14 | -## Redirect to the Samsung license file protected builds. |
15 | +## Redirect to the license file protected builds. |
16 | RewriteCond %{REQUEST_URI} !^/$ |
17 | RewriteRule .* /licenses/license.php [CO=downloadrequested:%{REQUEST_URI}:.%{ENV:CO_DOMAIN}:5:/,L,R] |
18 | |
19 | -## Return "Permission denied" if no EULA/OPEN-EULA exists |
20 | +## Return "Permission denied" if no EULA/OPEN-EULA/BUILD-INFO exists |
21 | RewriteCond %{REQUEST_URI} !^/$ |
22 | RewriteCond %{REQUEST_URI} !^/licenses/.*$ |
23 | RewriteCond %{ENV:LP_DOWNLOAD_DIR}/EULA.txt !-f |
24 | RewriteCond %{ENV:LP_DOWNLOAD_DIR}/OPEN-EULA.txt !-f |
25 | +RewriteCond %{ENV:LP_DOWNLOAD_DIR}/BUILD-INFO.txt !-f |
26 | RewriteRule .* - [R=403,L] |
27 | |
28 | === added directory 'android/build-info' |
29 | === added file 'android/build-info/BUILD-INFO.txt' |
30 | --- android/build-info/BUILD-INFO.txt 1970-01-01 00:00:00 +0000 |
31 | +++ android/build-info/BUILD-INFO.txt 2012-06-11 10:48:21 +0000 |
32 | @@ -0,0 +1,38 @@ |
33 | +Format-Version: 0.1 |
34 | + |
35 | +Files-Pattern: *snowball* |
36 | +Build-Name: landing-snowball |
37 | +Theme: ste |
38 | +License-Type: protected |
39 | +License-Text: <p>IMPORTANT — PLEASE READ THE FOLLOWING AGREEMENT CAREFULLY.</p> |
40 | + <p> |
41 | + THIS IS A LEGALLY BINDING AGREEMENT BETWEEN YOU, an individual or a |
42 | + legal entity, (“LICENSEE”) AND SAMSUNG ELECTRONICS CO., |
43 | + LTD. (“SAMSUNG”). BY CLICKING THE "ACCEPT" BUTTON, OR BY DOWNLOADING OR |
44 | + INSTALLING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE |
45 | + TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS |
46 | + AGREEMENT OR ARE NOT AUTHORISED TO ACCEPT AND AGREE TO THE TERMS OF THE |
47 | + AGREEMENT ON BEHALF OF YOUR LEGAL ENTITY, DO NOT DOWNLOAD, INSTALL OR |
48 | + OTHERWISE USE THE SOFTWARE. |
49 | + </p> |
50 | + |
51 | +Files-Pattern: *origen* |
52 | +Build-Name: landing-origen |
53 | +Theme: samsung |
54 | +License-Type: protected |
55 | +License-Text: <p>IMPORTANT — PLEASE READ THE FOLLOWING AGREEMENT CAREFULLY.</p> |
56 | + <p> |
57 | + THIS IS A LEGALLY BINDING AGREEMENT BETWEEN YOU, an individual or a |
58 | + legal entity, (“LICENSEE”) AND SAMSUNG ELECTRONICS CO., |
59 | + LTD. (“SAMSUNG”). BY CLICKING THE "ACCEPT" BUTTON, OR BY DOWNLOADING OR |
60 | + INSTALLING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE |
61 | + TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS |
62 | + AGREEMENT OR ARE NOT AUTHORISED TO ACCEPT AND AGREE TO THE TERMS OF THE |
63 | + AGREEMENT ON BEHALF OF YOUR LEGAL ENTITY, DO NOT DOWNLOAD, INSTALL OR |
64 | + OTHERWISE USE THE SOFTWARE. |
65 | + </p> |
66 | + |
67 | +Files-Pattern: *panda* |
68 | +Build-Name: landing-panda |
69 | +License-Type: open |
70 | + |
71 | |
72 | === added file 'android/build-info/origen-blob.txt' |
73 | --- android/build-info/origen-blob.txt 1970-01-01 00:00:00 +0000 |
74 | +++ android/build-info/origen-blob.txt 2012-06-11 10:48:21 +0000 |
75 | @@ -0,0 +1,1 @@ |
76 | +This is protected with click-through Samsung license. |
77 | \ No newline at end of file |
78 | |
79 | === added file 'android/build-info/panda-open.txt' |
80 | --- android/build-info/panda-open.txt 1970-01-01 00:00:00 +0000 |
81 | +++ android/build-info/panda-open.txt 2012-06-11 10:48:21 +0000 |
82 | @@ -0,0 +1,1 @@ |
83 | +This is always available. |
84 | |
85 | === added file 'android/build-info/snowball-blob.txt' |
86 | --- android/build-info/snowball-blob.txt 1970-01-01 00:00:00 +0000 |
87 | +++ android/build-info/snowball-blob.txt 2012-06-11 10:48:21 +0000 |
88 | @@ -0,0 +1,1 @@ |
89 | +This is protected with click-through ST-E license. |
90 | \ No newline at end of file |
91 | |
92 | === added file 'licenses/BuildInfo.php' |
93 | --- licenses/BuildInfo.php 1970-01-01 00:00:00 +0000 |
94 | +++ licenses/BuildInfo.php 2012-06-11 10:48:21 +0000 |
95 | @@ -0,0 +1,168 @@ |
96 | +<?php |
97 | + |
98 | +class BuildInfo |
99 | +{ |
100 | + private $build_info_array; |
101 | + private $fields_defined; |
102 | + private $multiline_vars; |
103 | + private $search_path; |
104 | + private $fname; |
105 | + private $file_info_array; |
106 | + |
107 | + public function __construct($fn) |
108 | + { |
109 | + $this->build_info_array = array(); |
110 | + $this->file_info_array = array(); |
111 | + $this->fields_defined = array("Format-Version", "Files-Pattern", |
112 | + "Build-Name", "Theme", "License-Type", "OpenID-Launchpad-Teams", |
113 | + "Collect-User-Data", "License-Text"); |
114 | + $this->multiline_vars = array("License-Text"); |
115 | + $this->search_path = dirname($fn); |
116 | + $this->fname = basename($fn); |
117 | + $this->build_info_file = $this->search_path."/BUILD-INFO.txt"; |
118 | + $data = $this->readFile(); |
119 | + if (is_array($data)) { |
120 | + $this->build_info_array = $this->parseData($data); |
121 | + $this->file_info_array = $this->getInfoForFile($this->fname); |
122 | + } |
123 | + } |
124 | + |
125 | + public function readFile() |
126 | + { |
127 | + $data = array(); |
128 | + if (is_dir($this->build_info_file) or !is_file($this->build_info_file) or filesize($this->build_info_file) == 0) return false; |
129 | + $file = fopen($this->build_info_file, "r") or exit("Unable to open file $this->build_info_file!"); |
130 | + while(!feof($file)) { |
131 | + $line = fgets($file); |
132 | + if (trim($line) == "") |
133 | + continue; |
134 | + $data[] = $line; |
135 | + } |
136 | + return $data; |
137 | + } |
138 | + |
139 | + private function getInfoForFile($fname) |
140 | + { |
141 | + /** |
142 | + * Get array of fields for corresponding file |
143 | + */ |
144 | + foreach (array_keys($this->build_info_array) as $key) |
145 | + if ($key != 'Format-Version') { |
146 | + $files = glob($this->search_path."/".$key); |
147 | + foreach ($files as $file) |
148 | + if ($file == $this->search_path."/".$fname) |
149 | + return $this->build_info_array[$key]; |
150 | + } |
151 | + return array(); |
152 | + } |
153 | + |
154 | + public function getFormatVersion() |
155 | + { |
156 | + if (array_key_exists('Format-Version', $this->build_info_array)) |
157 | + return $this->build_info_array["Format-Version"]; |
158 | + else |
159 | + return false; |
160 | + } |
161 | + |
162 | + // Get value of specified field for corresponding file |
163 | + public function get($field) |
164 | + { |
165 | + if (array_key_exists($field, $this->file_info_array)) |
166 | + return $this->file_info_array[$field]; |
167 | + else |
168 | + return false; |
169 | + } |
170 | + |
171 | + public function parseLine($line) { |
172 | + $values = explode(":", $line, 2); |
173 | + if ($values === false || count($values) != 2) { |
174 | + throw new InvalidArgumentException("Line is not in the correct format."); |
175 | + } else { |
176 | + $field = trim($values[0]); |
177 | + $value = trim($values[1]); |
178 | + if (!$this->isValidField($field)) { |
179 | + throw new InvalidArgumentException("Field '$field' not allowed."); |
180 | + } else { |
181 | + return array($field => $value); |
182 | + } |
183 | + } |
184 | + } |
185 | + |
186 | + public function isValidField($field_name) { |
187 | + if (in_array($field_name, $this->fields_defined)) { |
188 | + return true; |
189 | + } else { |
190 | + return false; |
191 | + } |
192 | + } |
193 | + |
194 | + public function parseContinuation($lines, &$line_no) { |
195 | + $text = ''; |
196 | + $total_lines = count($lines); |
197 | + while ($line_no < $total_lines && |
198 | + strlen($lines[$line_no]) > 0) { |
199 | + if ($lines[$line_no][0] == ' ') { |
200 | + $text .= "\n" . substr($lines[$line_no], 1); |
201 | + $line_no++; |
202 | + } else { |
203 | + break; |
204 | + } |
205 | + } |
206 | + return $text; |
207 | + } |
208 | + |
209 | + /** |
210 | + * `data` should be array of lines. |
211 | + */ |
212 | + public function parseData($data) { |
213 | + if (!is_array($data)) { |
214 | + throw new InvalidArgumentException("No array provided."); |
215 | + } |
216 | + $format_line = array_shift($data); |
217 | + $values = $this->parseLine($format_line); |
218 | + if (!array_key_exists("Format-Version", $values)) { |
219 | + throw new InvalidArgumentException("Data in incorrect format."); |
220 | + } |
221 | + $result = array("Format-Version" => $values["Format-Version"]); |
222 | + |
223 | + $line_no = 0; |
224 | + while ($line_no < count($data)) { |
225 | + $line = $data[$line_no]; |
226 | + $values = $this->parseLine($line); |
227 | + if (array_key_exists("Files-Pattern", $values)) { |
228 | + $line_no++; |
229 | + $block = $this->parseBlock($data, $line_no); |
230 | + if (is_array($block)) { |
231 | + foreach (explode(",", $values["Files-Pattern"]) as $pattern) { |
232 | + $result[$pattern] = $block; |
233 | + } |
234 | + } |
235 | + } |
236 | + } |
237 | + return $result; |
238 | + } |
239 | + |
240 | + public function parseBlock($data, &$line_no) { |
241 | + $result = array(); |
242 | + |
243 | + if (!is_array($data)) { |
244 | + throw new InvalidArgumentException("No array provided."); |
245 | + } |
246 | + while ($line_no < count($data)) { |
247 | + $line = $data[$line_no]; |
248 | + $values = $this->parseLine($line); |
249 | + if (array_key_exists("License-Text", $values)) { |
250 | + $text = $values["License-Text"]; |
251 | + $line_no++; |
252 | + $text .= $this->parseContinuation($data, $line_no); |
253 | + $result["License-Text"] = $text; |
254 | + } elseif (array_key_exists("Files-Pattern", $values)) { |
255 | + return $result; |
256 | + } else { |
257 | + $line_no++; |
258 | + $result = array_merge($result, $values); |
259 | + } |
260 | + } |
261 | + return $result; |
262 | + } |
263 | +} |
264 | |
265 | === modified file 'licenses/license.php' |
266 | --- licenses/license.php 2012-05-11 08:23:42 +0000 |
267 | +++ licenses/license.php 2012-06-11 10:48:21 +0000 |
268 | @@ -1,6 +1,7 @@ |
269 | <?php |
270 | |
271 | require_once("LicenseHelper.php"); |
272 | +require_once("BuildInfo.php"); |
273 | |
274 | $down = $_COOKIE["downloadrequested"]; |
275 | $host = $_SERVER["HTTP_HOST"]; |
276 | @@ -9,55 +10,78 @@ |
277 | $fn = $doc.$down; // Filename on server |
278 | $flist = array(); |
279 | $eula = ''; |
280 | +$bi_found = 0; |
281 | |
282 | if (preg_match("/.*openid.*/", $fn) or preg_match("/.*restricted.*/", $fn) or preg_match("/.*private.*/", $fn)) { |
283 | - LicenseHelper::redirect_with_status($down, $domain, 200); |
284 | + LicenseHelper::redirect_with_status($down, $domain, 200); |
285 | } |
286 | |
287 | if (file_exists($fn) and LicenseHelper::checkFile($fn)) { // Requested download is file |
288 | - $search_dir = dirname($fn); |
289 | - $repl = dirname($down); |
290 | - $name_only = array(basename($down), ''); |
291 | + $search_dir = dirname($fn); |
292 | + $repl = dirname($down); |
293 | + $name_only = array(basename($down), ''); |
294 | } elseif (is_dir($fn)) { // Requested download is directory |
295 | - $search_dir = $fn; |
296 | - $repl = $down; |
297 | - $name_only = array(); |
298 | + $search_dir = $fn; |
299 | + $repl = $down; |
300 | + $name_only = array(); |
301 | } else { // Requested download not found on server |
302 | - LicenseHelper::redirect_with_status($down, $domain, 404); |
303 | + LicenseHelper::redirect_with_status($down, $domain, 404); |
304 | } |
305 | |
306 | -$flist = LicenseHelper::getFilesList($search_dir); |
307 | - |
308 | -if (!empty($name_only)) { |
309 | - $pattern = "/^".$name_only[0]."\.EULA\.txt.*/"; |
310 | - $eula = LicenseHelper::findFileByPattern($flist, $pattern); |
311 | +if (file_exists($search_dir."/BUILD-INFO.txt")) { |
312 | + $bi_found = 1; |
313 | + $bi = new BuildInfo($search_dir."/".$name_only[0]); |
314 | + $theme = $bi->get("Theme"); |
315 | + $lic_type = $bi->get("License-Type"); |
316 | + $lic_text = $bi->get("License-Text"); |
317 | +} else { |
318 | + $flist = LicenseHelper::getFilesList($search_dir); |
319 | + if (!empty($name_only)) { |
320 | + $pattern = "/^".$name_only[0]."\.EULA\.txt.*/"; |
321 | + $eula = LicenseHelper::findFileByPattern($flist, $pattern); |
322 | + } |
323 | } |
324 | |
325 | if (LicenseHelper::checkFile($fn)) { |
326 | - if (LicenseHelper::checkFile($doc."/".$repl."/".$eula)) { // Special EULA found |
327 | - $theme = LicenseHelper::getTheme($eula, $down); |
328 | - } elseif (LicenseHelper::checkFile($doc."/".$repl."/EULA.txt")) { // No special EULA found |
329 | - $theme = LicenseHelper::getTheme("EULA.txt", $down); |
330 | - } elseif (LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")) { |
331 | - // If file is requested but no special EULA for it and no EULA.txt is present, |
332 | - // look for any EULA and if found decide that current file is not protected. |
333 | - LicenseHelper::redirect_with_status($down, $domain, 200); |
334 | - } else { |
335 | - LicenseHelper::redirect_with_status($down, $domain, 403); |
336 | - } |
337 | + if ($bi_found) { |
338 | + if ($lic_type == 'open') |
339 | + LicenseHelper::redirect_with_status($down, $domain, 200); |
340 | + elseif (($theme != false) or ($lic_text != false)) |
341 | + $template_content = file_get_contents($doc."/licenses/".$theme.".html"); |
342 | + else |
343 | + LicenseHelper::redirect_with_status($down, $domain, 403); |
344 | + } else { |
345 | + if (LicenseHelper::checkFile($doc."/".$repl."/".$eula)) { |
346 | + // Special EULA found |
347 | + $theme = LicenseHelper::getTheme($eula, $down); |
348 | + } elseif (LicenseHelper::checkFile($doc."/".$repl."/EULA.txt")) { |
349 | + // No special EULA found |
350 | + $theme = LicenseHelper::getTheme("EULA.txt", $down); |
351 | + } elseif (LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")) { |
352 | + // If file is requested but no special EULA for it and no EULA.txt |
353 | + // is present, look for any EULA and if found decide that current |
354 | + // file is not protected. |
355 | + LicenseHelper::redirect_with_status($down, $domain, 200); |
356 | + } else { |
357 | + LicenseHelper::redirect_with_status($down, $domain, 403); |
358 | + } |
359 | + $template_content = file_get_contents($doc."/licenses/".$theme.".html"); |
360 | + $lic_text = file_get_contents($doc."/licenses/".$theme.".txt"); |
361 | + } |
362 | } elseif (is_dir($fn)) { |
363 | - if (empty($flist) or LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")) { // Directory contains only subdirs or any EULA |
364 | - LicenseHelper::redirect_with_status($down, $domain, 200); |
365 | - } else { // No special EULA, no EULA.txt, no OPEN-EULA.txt found |
366 | - LicenseHelper::redirect_with_status($down, $domain, 403); |
367 | - } |
368 | + if (empty($flist) |
369 | + or LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/") |
370 | + or $bi_found) { |
371 | + // Directory contains only subdirs or any EULA or BUILD-INFO.txt |
372 | + LicenseHelper::redirect_with_status($down, $domain, 200); |
373 | + } else { |
374 | + // No special EULA, no EULA.txt, no OPEN-EULA.txt found |
375 | + LicenseHelper::redirect_with_status($down, $domain, 403); |
376 | + } |
377 | } else { |
378 | - LicenseHelper::redirect_with_status($down, $domain, 403); |
379 | + LicenseHelper::redirect_with_status($down, $domain, 403); |
380 | } |
381 | |
382 | -$template_content = file_get_contents($doc."/licenses/".$theme.".html"); |
383 | -$eula_content = file_get_contents($doc."/licenses/".$theme.".txt"); |
384 | - |
385 | -$out = str_replace("EULA.txt", $eula_content, $template_content); |
386 | +$out = str_replace("EULA.txt", $lic_text, $template_content); |
387 | echo $out; |
388 | ?> |
389 | |
390 | === added file 'tests/BUILD-INFO.txt' |
391 | --- tests/BUILD-INFO.txt 1970-01-01 00:00:00 +0000 |
392 | +++ tests/BUILD-INFO.txt 2012-06-11 10:48:21 +0000 |
393 | @@ -0,0 +1,18 @@ |
394 | +Format-Version: 0.1 |
395 | +Files-Pattern: *.txt |
396 | +Build-Name: landing-snowball |
397 | +Theme: stericsson |
398 | +License-Type: open |
399 | +OpenID-Launchpad-Teams: linaro,non-linaro |
400 | +Collect-User-Data: yes |
401 | +License-Text: <p>IMPORTANT — PLEASE READ THE FOLLOWING AGREEMENT CAREFULLY.</p> |
402 | + <p> |
403 | + THIS IS A LEGALLY BINDING AGREEMENT BETWEEN YOU, an individual or a |
404 | + legal entity, (“LICENSEE”) AND SAMSUNG ELECTRONICS CO., |
405 | + LTD. (“SAMSUNG”). BY CLICKING THE "ACCEPT" BUTTON, OR BY DOWNLOADING OR |
406 | + INSTALLING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE |
407 | + TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS |
408 | + AGREEMENT OR ARE NOT AUTHORISED TO ACCEPT AND AGREE TO THE TERMS OF THE |
409 | + AGREEMENT ON BEHALF OF YOUR LEGAL ENTITY, DO NOT DOWNLOAD, INSTALL OR |
410 | + OTHERWISE USE THE SOFTWARE. |
411 | + </p> |
412 | |
413 | === added file 'tests/BuildInfoTest.php' |
414 | --- tests/BuildInfoTest.php 1970-01-01 00:00:00 +0000 |
415 | +++ tests/BuildInfoTest.php 2012-06-11 10:48:21 +0000 |
416 | @@ -0,0 +1,244 @@ |
417 | +<?php |
418 | + |
419 | +require_once("licenses/BuildInfo.php"); |
420 | + |
421 | +class BuildInfoTest extends PHPUnit_Framework_TestCase |
422 | +{ |
423 | + |
424 | + private $temp_filename; |
425 | + private $good_bi; |
426 | + private $empty_bi; |
427 | + private $fname; |
428 | + |
429 | + public function setUp() |
430 | + { |
431 | + $this->good_bi = new BuildInfo("tests/BUILD-INFO.txt"); |
432 | + $this->temp_filename = tempnam(sys_get_temp_dir(), "build-info"); |
433 | + $this->empty_bi = new BuildInfo($this->temp_filename); |
434 | + $this->fname = "BUILD-INFO.txt"; |
435 | + } |
436 | + |
437 | + public function tearDown() { |
438 | + if (file_exists($this->temp_filename)) { |
439 | + unlink($this->temp_filename); |
440 | + } |
441 | + } |
442 | + |
443 | + /** |
444 | + * @expectedException InvalidArgumentException |
445 | + */ |
446 | + public function test_parseLine_fails() { |
447 | + $line = "no separator"; |
448 | + $buildinfo = new BuildInfo(""); |
449 | + $buildinfo->parseLine($line); |
450 | + } |
451 | + |
452 | + public function test_parseLine_passes() { |
453 | + $line = "Build-Name:value"; |
454 | + $buildinfo = new BuildInfo(""); |
455 | + $this->assertEquals(array("Build-Name" => "value"), |
456 | + $buildinfo->parseLine($line)); |
457 | + } |
458 | + |
459 | + public function test_parseLine_trims() { |
460 | + $line = "Build-Name: value"; |
461 | + $buildinfo = new BuildInfo(""); |
462 | + $this->assertEquals(array("Build-Name" => "value"), |
463 | + $buildinfo->parseLine($line)); |
464 | + } |
465 | + |
466 | + /** |
467 | + * @expectedException InvalidArgumentException |
468 | + */ |
469 | + public function test_parseLine_invalid_field() { |
470 | + $line = "field: value"; |
471 | + $buildinfo = new BuildInfo(""); |
472 | + $this->assertEquals(array("field" => "value"), |
473 | + $buildinfo->parseLine($line)); |
474 | + } |
475 | + |
476 | + public function test_isValidField_true() { |
477 | + $buildinfo = new BuildInfo(""); |
478 | + $fields_allowed = array("Format-Version", "Files-Pattern", |
479 | + "Build-Name", "Theme", "License-Type", "OpenID-Launchpad-Teams", |
480 | + "Collect-User-Data", "License-Text"); |
481 | + foreach ($fields_allowed as $field) { |
482 | + $this->assertTrue($buildinfo->isValidField($field)); |
483 | + } |
484 | + } |
485 | + |
486 | + public function test_isValidField_false() { |
487 | + $buildinfo = new BuildInfo(""); |
488 | + $this->assertFalse($buildinfo->isValidField("Some random text")); |
489 | + } |
490 | + |
491 | + /** |
492 | + * @expectedException InvalidArgumentException |
493 | + */ |
494 | + public function test_parseData_fails() { |
495 | + $buildinfo = new BuildInfo(""); |
496 | + $buildinfo->parseData(array("Arbitrary text")); |
497 | + } |
498 | + |
499 | + /** |
500 | + * @expectedException InvalidArgumentException |
501 | + */ |
502 | + public function test_parseData_array_expected() { |
503 | + $buildinfo = new BuildInfo(""); |
504 | + $buildinfo->parseData("Arbitrary text"); |
505 | + } |
506 | + |
507 | + public function test_parseData_format_version() { |
508 | + $buildinfo = new BuildInfo(""); |
509 | + $values = $buildinfo->parseData(array("Format-Version: 2.0")); |
510 | + $this->assertEquals(array("Format-Version" => "2.0"), |
511 | + $values); |
512 | + } |
513 | + |
514 | + public function test_parseData_extra_fields() { |
515 | + $buildinfo = new BuildInfo(""); |
516 | + $values = $buildinfo->parseData(array( |
517 | + "Format-Version: 2.0", |
518 | + "Files-Pattern: *.txt", |
519 | + "Build-Name: woohoo")); |
520 | + $this->assertEquals(array("Format-Version" => "2.0", |
521 | + "*.txt" => array("Build-Name" => "woohoo")), |
522 | + $values); |
523 | + } |
524 | + |
525 | + public function test_parseBlock_license() { |
526 | + $buildinfo = new BuildInfo(""); |
527 | + $lineno = 0; |
528 | + $values = $buildinfo->parseBlock(array( |
529 | + "Format-Version: 2.0", |
530 | + "License-Text: line1", |
531 | + " line2"), $lineno); |
532 | + $this->assertEquals(array("Format-Version" => "2.0", |
533 | + "License-Text" => "line1\nline2"), |
534 | + $values); |
535 | + } |
536 | + |
537 | + public function test_parseContinuation_no_continuation() { |
538 | + $buildinfo = new BuildInfo(""); |
539 | + $lineno = 0; |
540 | + $this->assertEquals( |
541 | + "", |
542 | + $buildinfo->parseContinuation(array("no-space"), $lineno)); |
543 | + } |
544 | + |
545 | + public function test_parseContinuation_indexed() { |
546 | + $buildinfo = new BuildInfo(""); |
547 | + $lineno = 0; |
548 | + $this->assertEquals("", |
549 | + $buildinfo->parseContinuation(array("no-space", " space"), $lineno)); |
550 | + } |
551 | + |
552 | + public function test_parseContinuation() { |
553 | + $buildinfo = new BuildInfo(""); |
554 | + $lineno = 1; |
555 | + $value = $buildinfo->parseContinuation(array("no-space", " line1", " line2"), $lineno); |
556 | + $this->assertEquals("\nline1\nline2", $value); |
557 | + } |
558 | + |
559 | + /** |
560 | + * @expectedException InvalidArgumentException |
561 | + */ |
562 | + public function test_parseData_no_format_version_fails() { |
563 | + $buildinfo = new BuildInfo(""); |
564 | + $values = $buildinfo->parseData(array("Build-Name: blah")); |
565 | + } |
566 | + |
567 | + public function test_parseData_blocks() { |
568 | + $buildinfo = new BuildInfo(""); |
569 | + $lineno = 0; |
570 | + $values = $buildinfo->parseData(array("Format-Version: 2.0", |
571 | + "Files-Pattern: *.txt", |
572 | + "Build-Name: woohoo", |
573 | + "Files-Pattern: *.tgz", |
574 | + "Build-Name: weehee")); |
575 | + $this->assertEquals(array("Format-Version" => "2.0", |
576 | + "*.txt" => array("Build-Name" => "woohoo"), |
577 | + "*.tgz" => array("Build-Name" => "weehee")), |
578 | + $values); |
579 | + } |
580 | + |
581 | + public function test_parseData_block_multiple_patterns() { |
582 | + $buildinfo = new BuildInfo(""); |
583 | + $lineno = 0; |
584 | + $values = $buildinfo->parseData(array("Format-Version: 2.0", |
585 | + "Files-Pattern: *.txt,*.tgz", |
586 | + "Build-Name: weehee")); |
587 | + $this->assertEquals(array("Format-Version" => "2.0", |
588 | + "*.txt" => array("Build-Name" => "weehee"), |
589 | + "*.tgz" => array("Build-Name" => "weehee")), |
590 | + $values); |
591 | + } |
592 | + |
593 | + |
594 | + /** |
595 | + * Running readFile on a directory returns false. |
596 | + */ |
597 | + public function test_readFile_nonFile() |
598 | + { |
599 | + $bi = new BuildInfo(dirname(__FILE__)); |
600 | + $this->assertFalse($bi->readFile()); |
601 | + } |
602 | + |
603 | + /** |
604 | + * Running readFile on a nonexistent file returns false. |
605 | + */ |
606 | + public function test_readFile_nonexistentFile() |
607 | + { |
608 | + $bi = new BuildInfo("nonexistent.file"); |
609 | + $this->assertFalse($bi->readFile()); |
610 | + } |
611 | + |
612 | + /** |
613 | + * Running readFile on a regular file returns array of strings. |
614 | + */ |
615 | + public function test_readFile_file() |
616 | + { |
617 | + $bi = new BuildInfo("tests/BUILD-INFO.txt"); |
618 | + $this->assertInternalType('array', $bi->readFile()); |
619 | + } |
620 | + |
621 | + /** |
622 | + * Running 'get' functions on an empty fields returns false. |
623 | + */ |
624 | + public function test_getFormatVersion_empty() |
625 | + { |
626 | + $this->assertFalse($this->empty_bi->getFormatVersion()); |
627 | + } |
628 | + |
629 | + /** |
630 | + * Running 'get' functions on non-empty fields returns string value. |
631 | + */ |
632 | + public function test_getFormatVersion_type() |
633 | + { |
634 | + $this->assertInternalType( |
635 | + 'string', $this->good_bi->getFormatVersion()); |
636 | + } |
637 | + |
638 | + public function test_getFormatVersion() |
639 | + { |
640 | + $this->assertEquals('0.1', $this->good_bi->getFormatVersion()); |
641 | + } |
642 | + |
643 | + public function test_getBuildName_empty() |
644 | + { |
645 | + $this->assertFalse($this->empty_bi->get("Build-Name")); |
646 | + } |
647 | + |
648 | + public function test_getBuildName_type() |
649 | + { |
650 | + $this->assertInternalType( |
651 | + 'string', $this->good_bi->get("Build-Name")); |
652 | + } |
653 | + |
654 | + public function test_getBuildName() |
655 | + { |
656 | + $this->assertEquals( |
657 | + 'landing-snowball', $this->good_bi->get("Build-Name")); |
658 | + } |
659 | +} |
660 | +?> |
661 | |
662 | === modified file 'tests/LicenseHelperTest.php' |
663 | --- tests/LicenseHelperTest.php 2012-05-29 07:30:45 +0000 |
664 | +++ tests/LicenseHelperTest.php 2012-06-11 10:48:21 +0000 |
665 | @@ -174,4 +174,4 @@ |
666 | |
667 | } |
668 | |
669 | -?> |
670 | \ No newline at end of file |
671 | +?> |
672 | |
673 | === modified file 'tests/test_click_through_license.py' |
674 | --- tests/test_click_through_license.py 2012-05-17 18:44:59 +0000 |
675 | +++ tests/test_click_through_license.py 2012-06-11 10:48:21 +0000 |
676 | @@ -36,6 +36,9 @@ |
677 | per_file_ste_test_file = '/android/images/snowball-blob.txt' |
678 | per_file_not_protected_test_file = '/android/images/MANIFEST' |
679 | dirs_only_dir = '/android/~linaro-android/' |
680 | +build_info_samsung_test_file = '/android/build-info/origen-blob.txt' |
681 | +build_info_ste_test_file = '/android/build-info/snowball-blob.txt' |
682 | +build_info_not_protected_test_file = '/android/build-info/panda-open.txt' |
683 | |
684 | |
685 | class Contains(object): |
686 | @@ -295,3 +298,25 @@ |
687 | search = "Not Found" |
688 | testfile = fetcher.get(host + not_found_test_file) |
689 | self.assertThat(testfile, Contains(search)) |
690 | + |
691 | + def test_build_info_non_protected_file(self): |
692 | + search = "This is always available." |
693 | + testfile = fetcher.get(host + build_info_not_protected_test_file) |
694 | + self.assertThat(testfile, Contains(search)) |
695 | + |
696 | + def test_build_info_accept_license_samsung_file(self): |
697 | + search = "This is protected with click-through Samsung license." |
698 | + testfile = fetcher.get(host + build_info_samsung_test_file) |
699 | + fetcher.close() |
700 | + if os.path.exists("%s/cookies.txt" % docroot): |
701 | + os.rename("%s/cookies.txt" % docroot, |
702 | + "%s/cookies.samsung" % docroot) |
703 | + self.assertThat(testfile, Contains(search)) |
704 | + |
705 | + def test_build_info_accept_license_ste_file(self): |
706 | + search = "This is protected with click-through ST-E license." |
707 | + testfile = fetcher.get(host + build_info_ste_test_file) |
708 | + fetcher.close() |
709 | + if os.path.exists("%s/cookies.txt" % docroot): |
710 | + os.rename("%s/cookies.txt" % docroot, "%s/cookies.ste" % docroot) |
711 | + self.assertThat(testfile, Contains(search)) |
712 | |
713 | === modified file 'tests/test_php_unit.py' |
714 | --- tests/test_php_unit.py 2012-05-28 09:35:50 +0000 |
715 | +++ tests/test_php_unit.py 2012-06-11 10:48:21 +0000 |
716 | @@ -17,7 +17,7 @@ |
717 | super(PhpUnitTest, self).setUp() |
718 | self.xml_path = tempfile.mkstemp()[1] |
719 | returncode = subprocess.Popen(['phpunit', '--log-junit', |
720 | - self.xml_path, 'tests/LicenseHelperTest'], |
721 | + self.xml_path, 'tests'], |
722 | stdout=open('/dev/null', 'w'), |
723 | stderr=subprocess.STDOUT).wait() |
724 | if returncode == -1: |
Nice work gesha.
I have one general proposal: The license text should be extracted from
the build info file and put in the separate file in the same directory
as the build info file.
Few comments on the code also:
> DOWNLOAD_ DIR}/EULA. txt !-f DOWNLOAD_ DIR}/OPEN- EULA.txt !-f DOWNLOAD_ DIR}/BUILD- INFO.txt !-f
> @@ -102,4 +102,5 @@
> RewriteCond %{REQUEST_URI} !^/licenses/.*$
> RewriteCond %{ENV:LP_
> RewriteCond %{ENV:LP_
> +RewriteCond %{ENV:LP_
> RewriteRule .* - [R=403,L]
A comment above this block should be updated to match the new Build info
change.
> === added file 'licenses/ BuildInfo. php' BuildInfo. php 1970-01-01 00:00:00 +0000 BuildInfo. php 2012-05-28 09:45:23 +0000 Format- Version" , "Files-Pattern", Launchpad- Teams", User-Data" , "License-Text"); License- Text");
> --- licenses/
> +++ licenses/
> @@ -0,0 +1,151 @@
> +<?php
> +
> +class BuildInfo
> +{
> + private $text_array = array();
> + private $fields_defined = array("
> + "Build-Name", "Theme", "License-Type", "OpenID-
> + "Collect-
> + private $multiline_vars = array("
> + private $search_path = '';
> +
I like using __construct method and do all the class attribute setup in
there, that way is more readable.
Also, since your build file is something always unique to the build info
instance, you can make it an attribute of the class, and then just
assign it during class initialization. Something like:
$bi = BuildInfo( "build_ info.txt" );
$bi->readFile();
...
> + public function readFile($fn)
> + {
> + $this->search_path = dirname($fn);
> + $field = '';
> + $fp_read = 0;
> + if (is_dir($fn) or !is_file($fn) or filesize($fn) == 0) return false; is
> + $file = fopen($fn, "r") or exit("Unable to open file $fn!");
There are exceptions in PHP as well, I started using them in the project
so I think it should be good idea that we stick with that.
> + // Get the 'Format-Version' field.
> + $line = fgets($file);
> + $fields = explode(":", $line, "2");
This is good, you ensure that second and any other ":" char is ignored.
...
> + // Get the rest fileds.
> + while(!feof($file)) {
> + if ($fp_read) {
> + print_r($fields);
Is this some leftover debugging? Please remove.
> + $this-> text_array[ $fields[ 0]] = trim($fields[1]); $fields[ 0], $this-> multiline_ vars)) { $fields[ 0]] = trim($fields[1]);
> + $fp_read = 0;
> + }
> + $line = fgets($file);
> + if (trim($line) == "")
> + continue;
> + $fields = explode(":", $line, "2");
> + if ($fields[0] == "Files-Pattern") {
> + $tmp_arr = array();
> + $fp = trim($fields[1]);
> + while(!feof($file)) {
> + $line = fgets($file);
> + if (trim($line) == "")
> + continue;
> + $fields = explode(":", $line, "2");
> + if (in_array(
> + $field = $fields[0];
> + if (isset($fields[1]))
> + $tmp_arr[
> + while...