Merge lp:~gesha/linaro-license-protection/build-info-support into lp:~linaro-automation/linaro-license-protection/trunk

Proposed by Georgy Redkozubov
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
Reviewer Review Type Date Requested Status
Stevan Radaković Approve
Данило Шеган Pending
Review via email: mp+107599@code.launchpad.net

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.

To post a comment you must log in.
85. By Georgy Redkozubov

Added missing files

86. By Georgy Redkozubov

[merge] Fix php unit wrong error message when tests are failing.

Revision history for this message
Stevan Radaković (stevanr) wrote :
Download full text (21.3 KiB)

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:

>
> @@ -102,4 +102,5 @@
> RewriteCond %{REQUEST_URI} !^/licenses/.*$
> RewriteCond %{ENV:LP_DOWNLOAD_DIR}/EULA.txt !-f
> RewriteCond %{ENV:LP_DOWNLOAD_DIR}/OPEN-EULA.txt !-f
> +RewriteCond %{ENV:LP_DOWNLOAD_DIR}/BUILD-INFO.txt !-f
> RewriteRule .* - [R=403,L]

A comment above this block should be updated to match the new Build info
change.

> === added file 'licenses/BuildInfo.php'
> --- licenses/BuildInfo.php 1970-01-01 00:00:00 +0000
> +++ licenses/BuildInfo.php 2012-05-28 09:45:23 +0000
> @@ -0,0 +1,151 @@
> +<?php
> +
> +class BuildInfo
> +{
> + private $text_array = array();
> + private $fields_defined = array("Format-Version", "Files-Pattern",
> + "Build-Name", "Theme", "License-Type", "OpenID-Launchpad-Teams",
> + "Collect-User-Data", "License-Text");
> + private $multiline_vars = array("License-Text");
> + 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]);
> + $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($fields[0], $this->multiline_vars)) {
> + $field = $fields[0];
> + if (isset($fields[1]))
> + $tmp_arr[$fields[0]] = trim($fields[1]);
> + while...

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

Revision history for this message
Georgy Redkozubov (gesha) wrote :
Download full text (5.5 KiB)

> 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->text_array[$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($fields[0], $this->multiline_vars)) {
> > + $field = $fields[0];
> > + if (isset($fields[1]))
> > + $tmp_arr[$fields[0]] = trim($fields[1]);
> > + while(!feof($file)) {
> > + $line = fgets($file);
> > + if (trim($line) == "")
> > + continue;
> > + $fields = explode(":", $line, "2");
> > + if(in_array($fields[0], $this->fields_defined))
> {
> > + 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[$fields[0]] = trim($fields[1]);
> > + }
> > + }
> > + $this->text_array[$fp] = $tmp_arr;
> > + 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...

Read more...

Revision history for this message
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

Revision history for this message
Stevan Radaković (stevanr) wrote :

Hi gesha,

Your additions look great!

Few small pointers tho:

92 === added file 'licenses/BuildInfo.php'
93 --- licenses/BuildInfo.php 1970-01-01 00:00:00 +0000
94 +++ licenses/BuildInfo.php 2012-06-05 14:32:19 +0000
95 @@ -0,0 +1,207 @@
96 +<?php
97 +
98 +class BuildInfo
99 +{
100 + private $text_array = array();
101 + private $fields_defined = array("Format-Version", "Files-Pattern",
102 + "Build-Name", "Theme", "License-Type", "OpenID-Launchpad-Teams",
103 + "Collect-User-Data", "License-Text");
104 + private $multiline_vars = array("License-Text");
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($fname)
133 + {
134 + /**
135 + * Get array of fields for corresponding file
136 + */
137 + foreach (array_keys($this->text_array) as $key)
138 + if ($key != 'Format-Version') {
139 + $files = glob($this->search_path."/".$key);
140 + foreach ($files as $file)
141 + if ($file == $this->search_path."/".$fname)
142 + return $this->text_array[$key];
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->getInfoForFile($fname);
168 + if (array_key_exists('Theme', $info))
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/test_click_through_license.py'
802 --- tests/test_click_through_license.py 2012-05-17 18:44:59 +0000
803 +++ tests/test_click_through_license.py 2012-06-05 14:32:19 +0000
804 @@ -36,6 +36,9 @@

Tests fail for these 3 new tests added..

review: Needs Fixing (code)
95. By Georgy Redkozubov

Refactored 'getX' methods into single 'get' method. Updated code to use new approach.

Revision history for this message
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/test_click_through_license.py'
> 802 --- tests/test_click_through_license.py 2012-05-17 18:44:59 +0000
> 803 +++ tests/test_click_through_license.py 2012-06-05 14:32:19 +0000
> 804 @@ -36,6 +36,9 @@
>
> Tests fail for these 3 new tests added..

That was by the mistype. Fixed.

Revision history for this message
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/test_click_through_license.py'
> > 802 --- tests/test_click_through_license.py 2012-05-17 18:44:59 +0000
> > 803 +++ tests/test_click_through_license.py 2012-06-05 14:32:19 +0000
> > 804 @@ -36,6 +36,9 @@
> >
> > Tests fail for these 3 new tests added..
>
> That was by the mistype. Fixed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.htaccess'
--- .htaccess 2012-05-11 12:03:32 +0000
+++ .htaccess 2012-06-11 10:48:21 +0000
@@ -1,4 +1,4 @@
1IndexIgnore HEADER* licenses *EULA*1IndexIgnore HEADER* licenses *EULA* BUILD-INFO.txt
2IndexOptions FancyIndexing HTMLTable2IndexOptions FancyIndexing HTMLTable
33
4RewriteEngine On4RewriteEngine On
@@ -93,13 +93,14 @@
93RewriteCond %{HTTP_COOKIE} redirectlicensephp=40493RewriteCond %{HTTP_COOKIE} redirectlicensephp=404
94RewriteRule .* - [CO=redirectlicensephp:INVALID:.%{ENV:CO_DOMAIN}:-1,L]94RewriteRule .* - [CO=redirectlicensephp:INVALID:.%{ENV:CO_DOMAIN}:-1,L]
9595
96## Redirect to the Samsung license file protected builds.96## Redirect to the license file protected builds.
97RewriteCond %{REQUEST_URI} !^/$ 97RewriteCond %{REQUEST_URI} !^/$
98RewriteRule .* /licenses/license.php [CO=downloadrequested:%{REQUEST_URI}:.%{ENV:CO_DOMAIN}:5:/,L,R]98RewriteRule .* /licenses/license.php [CO=downloadrequested:%{REQUEST_URI}:.%{ENV:CO_DOMAIN}:5:/,L,R]
9999
100## Return "Permission denied" if no EULA/OPEN-EULA exists100## Return "Permission denied" if no EULA/OPEN-EULA/BUILD-INFO exists
101RewriteCond %{REQUEST_URI} !^/$101RewriteCond %{REQUEST_URI} !^/$
102RewriteCond %{REQUEST_URI} !^/licenses/.*$102RewriteCond %{REQUEST_URI} !^/licenses/.*$
103RewriteCond %{ENV:LP_DOWNLOAD_DIR}/EULA.txt !-f103RewriteCond %{ENV:LP_DOWNLOAD_DIR}/EULA.txt !-f
104RewriteCond %{ENV:LP_DOWNLOAD_DIR}/OPEN-EULA.txt !-f104RewriteCond %{ENV:LP_DOWNLOAD_DIR}/OPEN-EULA.txt !-f
105RewriteCond %{ENV:LP_DOWNLOAD_DIR}/BUILD-INFO.txt !-f
105RewriteRule .* - [R=403,L]106RewriteRule .* - [R=403,L]
106107
=== added directory 'android/build-info'
=== added file 'android/build-info/BUILD-INFO.txt'
--- android/build-info/BUILD-INFO.txt 1970-01-01 00:00:00 +0000
+++ android/build-info/BUILD-INFO.txt 2012-06-11 10:48:21 +0000
@@ -0,0 +1,38 @@
1Format-Version: 0.1
2
3Files-Pattern: *snowball*
4Build-Name: landing-snowball
5Theme: ste
6License-Type: protected
7License-Text: <p>IMPORTANT — PLEASE READ THE FOLLOWING AGREEMENT CAREFULLY.</p>
8 <p>
9 THIS IS A LEGALLY BINDING AGREEMENT BETWEEN YOU, an individual or a
10 legal entity, (“LICENSEE”) AND SAMSUNG ELECTRONICS CO.,
11 LTD. (“SAMSUNG”). BY CLICKING THE "ACCEPT" BUTTON, OR BY DOWNLOADING OR
12 INSTALLING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE
13 TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS
14 AGREEMENT OR ARE NOT AUTHORISED TO ACCEPT AND AGREE TO THE TERMS OF THE
15 AGREEMENT ON BEHALF OF YOUR LEGAL ENTITY, DO NOT DOWNLOAD, INSTALL OR
16 OTHERWISE USE THE SOFTWARE.
17 </p>
18
19Files-Pattern: *origen*
20Build-Name: landing-origen
21Theme: samsung
22License-Type: protected
23License-Text: <p>IMPORTANT — PLEASE READ THE FOLLOWING AGREEMENT CAREFULLY.</p>
24 <p>
25 THIS IS A LEGALLY BINDING AGREEMENT BETWEEN YOU, an individual or a
26 legal entity, (“LICENSEE”) AND SAMSUNG ELECTRONICS CO.,
27 LTD. (“SAMSUNG”). BY CLICKING THE "ACCEPT" BUTTON, OR BY DOWNLOADING OR
28 INSTALLING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE
29 TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS
30 AGREEMENT OR ARE NOT AUTHORISED TO ACCEPT AND AGREE TO THE TERMS OF THE
31 AGREEMENT ON BEHALF OF YOUR LEGAL ENTITY, DO NOT DOWNLOAD, INSTALL OR
32 OTHERWISE USE THE SOFTWARE.
33 </p>
34
35Files-Pattern: *panda*
36Build-Name: landing-panda
37License-Type: open
38
039
=== added file 'android/build-info/origen-blob.txt'
--- android/build-info/origen-blob.txt 1970-01-01 00:00:00 +0000
+++ android/build-info/origen-blob.txt 2012-06-11 10:48:21 +0000
@@ -0,0 +1,1 @@
1This is protected with click-through Samsung license.
0\ No newline at end of file2\ No newline at end of file
13
=== added file 'android/build-info/panda-open.txt'
--- android/build-info/panda-open.txt 1970-01-01 00:00:00 +0000
+++ android/build-info/panda-open.txt 2012-06-11 10:48:21 +0000
@@ -0,0 +1,1 @@
1This is always available.
02
=== added file 'android/build-info/snowball-blob.txt'
--- android/build-info/snowball-blob.txt 1970-01-01 00:00:00 +0000
+++ android/build-info/snowball-blob.txt 2012-06-11 10:48:21 +0000
@@ -0,0 +1,1 @@
1This is protected with click-through ST-E license.
0\ No newline at end of file2\ No newline at end of file
13
=== added file 'licenses/BuildInfo.php'
--- licenses/BuildInfo.php 1970-01-01 00:00:00 +0000
+++ licenses/BuildInfo.php 2012-06-11 10:48:21 +0000
@@ -0,0 +1,168 @@
1<?php
2
3class BuildInfo
4{
5 private $build_info_array;
6 private $fields_defined;
7 private $multiline_vars;
8 private $search_path;
9 private $fname;
10 private $file_info_array;
11
12 public function __construct($fn)
13 {
14 $this->build_info_array = array();
15 $this->file_info_array = array();
16 $this->fields_defined = array("Format-Version", "Files-Pattern",
17 "Build-Name", "Theme", "License-Type", "OpenID-Launchpad-Teams",
18 "Collect-User-Data", "License-Text");
19 $this->multiline_vars = array("License-Text");
20 $this->search_path = dirname($fn);
21 $this->fname = basename($fn);
22 $this->build_info_file = $this->search_path."/BUILD-INFO.txt";
23 $data = $this->readFile();
24 if (is_array($data)) {
25 $this->build_info_array = $this->parseData($data);
26 $this->file_info_array = $this->getInfoForFile($this->fname);
27 }
28 }
29
30 public function readFile()
31 {
32 $data = array();
33 if (is_dir($this->build_info_file) or !is_file($this->build_info_file) or filesize($this->build_info_file) == 0) return false;
34 $file = fopen($this->build_info_file, "r") or exit("Unable to open file $this->build_info_file!");
35 while(!feof($file)) {
36 $line = fgets($file);
37 if (trim($line) == "")
38 continue;
39 $data[] = $line;
40 }
41 return $data;
42 }
43
44 private function getInfoForFile($fname)
45 {
46 /**
47 * Get array of fields for corresponding file
48 */
49 foreach (array_keys($this->build_info_array) as $key)
50 if ($key != 'Format-Version') {
51 $files = glob($this->search_path."/".$key);
52 foreach ($files as $file)
53 if ($file == $this->search_path."/".$fname)
54 return $this->build_info_array[$key];
55 }
56 return array();
57 }
58
59 public function getFormatVersion()
60 {
61 if (array_key_exists('Format-Version', $this->build_info_array))
62 return $this->build_info_array["Format-Version"];
63 else
64 return false;
65 }
66
67 // Get value of specified field for corresponding file
68 public function get($field)
69 {
70 if (array_key_exists($field, $this->file_info_array))
71 return $this->file_info_array[$field];
72 else
73 return false;
74 }
75
76 public function parseLine($line) {
77 $values = explode(":", $line, 2);
78 if ($values === false || count($values) != 2) {
79 throw new InvalidArgumentException("Line is not in the correct format.");
80 } else {
81 $field = trim($values[0]);
82 $value = trim($values[1]);
83 if (!$this->isValidField($field)) {
84 throw new InvalidArgumentException("Field '$field' not allowed.");
85 } else {
86 return array($field => $value);
87 }
88 }
89 }
90
91 public function isValidField($field_name) {
92 if (in_array($field_name, $this->fields_defined)) {
93 return true;
94 } else {
95 return false;
96 }
97 }
98
99 public function parseContinuation($lines, &$line_no) {
100 $text = '';
101 $total_lines = count($lines);
102 while ($line_no < $total_lines &&
103 strlen($lines[$line_no]) > 0) {
104 if ($lines[$line_no][0] == ' ') {
105 $text .= "\n" . substr($lines[$line_no], 1);
106 $line_no++;
107 } else {
108 break;
109 }
110 }
111 return $text;
112 }
113
114 /**
115 * `data` should be array of lines.
116 */
117 public function parseData($data) {
118 if (!is_array($data)) {
119 throw new InvalidArgumentException("No array provided.");
120 }
121 $format_line = array_shift($data);
122 $values = $this->parseLine($format_line);
123 if (!array_key_exists("Format-Version", $values)) {
124 throw new InvalidArgumentException("Data in incorrect format.");
125 }
126 $result = array("Format-Version" => $values["Format-Version"]);
127
128 $line_no = 0;
129 while ($line_no < count($data)) {
130 $line = $data[$line_no];
131 $values = $this->parseLine($line);
132 if (array_key_exists("Files-Pattern", $values)) {
133 $line_no++;
134 $block = $this->parseBlock($data, $line_no);
135 if (is_array($block)) {
136 foreach (explode(",", $values["Files-Pattern"]) as $pattern) {
137 $result[$pattern] = $block;
138 }
139 }
140 }
141 }
142 return $result;
143 }
144
145 public function parseBlock($data, &$line_no) {
146 $result = array();
147
148 if (!is_array($data)) {
149 throw new InvalidArgumentException("No array provided.");
150 }
151 while ($line_no < count($data)) {
152 $line = $data[$line_no];
153 $values = $this->parseLine($line);
154 if (array_key_exists("License-Text", $values)) {
155 $text = $values["License-Text"];
156 $line_no++;
157 $text .= $this->parseContinuation($data, $line_no);
158 $result["License-Text"] = $text;
159 } elseif (array_key_exists("Files-Pattern", $values)) {
160 return $result;
161 } else {
162 $line_no++;
163 $result = array_merge($result, $values);
164 }
165 }
166 return $result;
167 }
168}
0169
=== modified file 'licenses/license.php'
--- licenses/license.php 2012-05-11 08:23:42 +0000
+++ licenses/license.php 2012-06-11 10:48:21 +0000
@@ -1,6 +1,7 @@
1<?php1<?php
22
3require_once("LicenseHelper.php");3require_once("LicenseHelper.php");
4require_once("BuildInfo.php");
45
5$down = $_COOKIE["downloadrequested"];6$down = $_COOKIE["downloadrequested"];
6$host = $_SERVER["HTTP_HOST"];7$host = $_SERVER["HTTP_HOST"];
@@ -9,55 +10,78 @@
9$fn = $doc.$down; // Filename on server10$fn = $doc.$down; // Filename on server
10$flist = array();11$flist = array();
11$eula = '';12$eula = '';
13$bi_found = 0;
1214
13if (preg_match("/.*openid.*/", $fn) or preg_match("/.*restricted.*/", $fn) or preg_match("/.*private.*/", $fn)) {15if (preg_match("/.*openid.*/", $fn) or preg_match("/.*restricted.*/", $fn) or preg_match("/.*private.*/", $fn)) {
14 LicenseHelper::redirect_with_status($down, $domain, 200);16 LicenseHelper::redirect_with_status($down, $domain, 200);
15}17}
1618
17if (file_exists($fn) and LicenseHelper::checkFile($fn)) { // Requested download is file19if (file_exists($fn) and LicenseHelper::checkFile($fn)) { // Requested download is file
18 $search_dir = dirname($fn);20 $search_dir = dirname($fn);
19 $repl = dirname($down);21 $repl = dirname($down);
20 $name_only = array(basename($down), '');22 $name_only = array(basename($down), '');
21} elseif (is_dir($fn)) { // Requested download is directory23} elseif (is_dir($fn)) { // Requested download is directory
22 $search_dir = $fn;24 $search_dir = $fn;
23 $repl = $down;25 $repl = $down;
24 $name_only = array();26 $name_only = array();
25} else { // Requested download not found on server27} else { // Requested download not found on server
26 LicenseHelper::redirect_with_status($down, $domain, 404);28 LicenseHelper::redirect_with_status($down, $domain, 404);
27}29}
2830
29$flist = LicenseHelper::getFilesList($search_dir);31if (file_exists($search_dir."/BUILD-INFO.txt")) {
3032 $bi_found = 1;
31if (!empty($name_only)) {33 $bi = new BuildInfo($search_dir."/".$name_only[0]);
32 $pattern = "/^".$name_only[0]."\.EULA\.txt.*/";34 $theme = $bi->get("Theme");
33 $eula = LicenseHelper::findFileByPattern($flist, $pattern);35 $lic_type = $bi->get("License-Type");
36 $lic_text = $bi->get("License-Text");
37} else {
38 $flist = LicenseHelper::getFilesList($search_dir);
39 if (!empty($name_only)) {
40 $pattern = "/^".$name_only[0]."\.EULA\.txt.*/";
41 $eula = LicenseHelper::findFileByPattern($flist, $pattern);
42 }
34}43}
3544
36if (LicenseHelper::checkFile($fn)) {45if (LicenseHelper::checkFile($fn)) {
37 if (LicenseHelper::checkFile($doc."/".$repl."/".$eula)) { // Special EULA found46 if ($bi_found) {
38 $theme = LicenseHelper::getTheme($eula, $down);47 if ($lic_type == 'open')
39 } elseif (LicenseHelper::checkFile($doc."/".$repl."/EULA.txt")) { // No special EULA found48 LicenseHelper::redirect_with_status($down, $domain, 200);
40 $theme = LicenseHelper::getTheme("EULA.txt", $down);49 elseif (($theme != false) or ($lic_text != false))
41 } elseif (LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")) {50 $template_content = file_get_contents($doc."/licenses/".$theme.".html");
42 // If file is requested but no special EULA for it and no EULA.txt is present,51 else
43 // look for any EULA and if found decide that current file is not protected.52 LicenseHelper::redirect_with_status($down, $domain, 403);
44 LicenseHelper::redirect_with_status($down, $domain, 200);53 } else {
45 } else {54 if (LicenseHelper::checkFile($doc."/".$repl."/".$eula)) {
46 LicenseHelper::redirect_with_status($down, $domain, 403);55 // Special EULA found
47 }56 $theme = LicenseHelper::getTheme($eula, $down);
57 } elseif (LicenseHelper::checkFile($doc."/".$repl."/EULA.txt")) {
58 // No special EULA found
59 $theme = LicenseHelper::getTheme("EULA.txt", $down);
60 } elseif (LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")) {
61 // If file is requested but no special EULA for it and no EULA.txt
62 // is present, look for any EULA and if found decide that current
63 // file is not protected.
64 LicenseHelper::redirect_with_status($down, $domain, 200);
65 } else {
66 LicenseHelper::redirect_with_status($down, $domain, 403);
67 }
68 $template_content = file_get_contents($doc."/licenses/".$theme.".html");
69 $lic_text = file_get_contents($doc."/licenses/".$theme.".txt");
70 }
48} elseif (is_dir($fn)) {71} elseif (is_dir($fn)) {
49 if (empty($flist) or LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")) { // Directory contains only subdirs or any EULA72 if (empty($flist)
50 LicenseHelper::redirect_with_status($down, $domain, 200);73 or LicenseHelper::findFileByPattern($flist, "/.*EULA.txt.*/")
51 } else { // No special EULA, no EULA.txt, no OPEN-EULA.txt found74 or $bi_found) {
52 LicenseHelper::redirect_with_status($down, $domain, 403);75 // Directory contains only subdirs or any EULA or BUILD-INFO.txt
53 }76 LicenseHelper::redirect_with_status($down, $domain, 200);
77 } else {
78 // No special EULA, no EULA.txt, no OPEN-EULA.txt found
79 LicenseHelper::redirect_with_status($down, $domain, 403);
80 }
54} else {81} else {
55 LicenseHelper::redirect_with_status($down, $domain, 403);82 LicenseHelper::redirect_with_status($down, $domain, 403);
56}83}
5784
58$template_content = file_get_contents($doc."/licenses/".$theme.".html");85$out = str_replace("EULA.txt", $lic_text, $template_content);
59$eula_content = file_get_contents($doc."/licenses/".$theme.".txt");
60
61$out = str_replace("EULA.txt", $eula_content, $template_content);
62echo $out;86echo $out;
63?>87?>
6488
=== added file 'tests/BUILD-INFO.txt'
--- tests/BUILD-INFO.txt 1970-01-01 00:00:00 +0000
+++ tests/BUILD-INFO.txt 2012-06-11 10:48:21 +0000
@@ -0,0 +1,18 @@
1Format-Version: 0.1
2Files-Pattern: *.txt
3Build-Name: landing-snowball
4Theme: stericsson
5License-Type: open
6OpenID-Launchpad-Teams: linaro,non-linaro
7Collect-User-Data: yes
8License-Text: <p>IMPORTANT — PLEASE READ THE FOLLOWING AGREEMENT CAREFULLY.</p>
9 <p>
10 THIS IS A LEGALLY BINDING AGREEMENT BETWEEN YOU, an individual or a
11 legal entity, (“LICENSEE”) AND SAMSUNG ELECTRONICS CO.,
12 LTD. (“SAMSUNG”). BY CLICKING THE "ACCEPT" BUTTON, OR BY DOWNLOADING OR
13 INSTALLING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE
14 TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS
15 AGREEMENT OR ARE NOT AUTHORISED TO ACCEPT AND AGREE TO THE TERMS OF THE
16 AGREEMENT ON BEHALF OF YOUR LEGAL ENTITY, DO NOT DOWNLOAD, INSTALL OR
17 OTHERWISE USE THE SOFTWARE.
18 </p>
019
=== added file 'tests/BuildInfoTest.php'
--- tests/BuildInfoTest.php 1970-01-01 00:00:00 +0000
+++ tests/BuildInfoTest.php 2012-06-11 10:48:21 +0000
@@ -0,0 +1,244 @@
1<?php
2
3require_once("licenses/BuildInfo.php");
4
5class BuildInfoTest extends PHPUnit_Framework_TestCase
6{
7
8 private $temp_filename;
9 private $good_bi;
10 private $empty_bi;
11 private $fname;
12
13 public function setUp()
14 {
15 $this->good_bi = new BuildInfo("tests/BUILD-INFO.txt");
16 $this->temp_filename = tempnam(sys_get_temp_dir(), "build-info");
17 $this->empty_bi = new BuildInfo($this->temp_filename);
18 $this->fname = "BUILD-INFO.txt";
19 }
20
21 public function tearDown() {
22 if (file_exists($this->temp_filename)) {
23 unlink($this->temp_filename);
24 }
25 }
26
27 /**
28 * @expectedException InvalidArgumentException
29 */
30 public function test_parseLine_fails() {
31 $line = "no separator";
32 $buildinfo = new BuildInfo("");
33 $buildinfo->parseLine($line);
34 }
35
36 public function test_parseLine_passes() {
37 $line = "Build-Name:value";
38 $buildinfo = new BuildInfo("");
39 $this->assertEquals(array("Build-Name" => "value"),
40 $buildinfo->parseLine($line));
41 }
42
43 public function test_parseLine_trims() {
44 $line = "Build-Name: value";
45 $buildinfo = new BuildInfo("");
46 $this->assertEquals(array("Build-Name" => "value"),
47 $buildinfo->parseLine($line));
48 }
49
50 /**
51 * @expectedException InvalidArgumentException
52 */
53 public function test_parseLine_invalid_field() {
54 $line = "field: value";
55 $buildinfo = new BuildInfo("");
56 $this->assertEquals(array("field" => "value"),
57 $buildinfo->parseLine($line));
58 }
59
60 public function test_isValidField_true() {
61 $buildinfo = new BuildInfo("");
62 $fields_allowed = array("Format-Version", "Files-Pattern",
63 "Build-Name", "Theme", "License-Type", "OpenID-Launchpad-Teams",
64 "Collect-User-Data", "License-Text");
65 foreach ($fields_allowed as $field) {
66 $this->assertTrue($buildinfo->isValidField($field));
67 }
68 }
69
70 public function test_isValidField_false() {
71 $buildinfo = new BuildInfo("");
72 $this->assertFalse($buildinfo->isValidField("Some random text"));
73 }
74
75 /**
76 * @expectedException InvalidArgumentException
77 */
78 public function test_parseData_fails() {
79 $buildinfo = new BuildInfo("");
80 $buildinfo->parseData(array("Arbitrary text"));
81 }
82
83 /**
84 * @expectedException InvalidArgumentException
85 */
86 public function test_parseData_array_expected() {
87 $buildinfo = new BuildInfo("");
88 $buildinfo->parseData("Arbitrary text");
89 }
90
91 public function test_parseData_format_version() {
92 $buildinfo = new BuildInfo("");
93 $values = $buildinfo->parseData(array("Format-Version: 2.0"));
94 $this->assertEquals(array("Format-Version" => "2.0"),
95 $values);
96 }
97
98 public function test_parseData_extra_fields() {
99 $buildinfo = new BuildInfo("");
100 $values = $buildinfo->parseData(array(
101 "Format-Version: 2.0",
102 "Files-Pattern: *.txt",
103 "Build-Name: woohoo"));
104 $this->assertEquals(array("Format-Version" => "2.0",
105 "*.txt" => array("Build-Name" => "woohoo")),
106 $values);
107 }
108
109 public function test_parseBlock_license() {
110 $buildinfo = new BuildInfo("");
111 $lineno = 0;
112 $values = $buildinfo->parseBlock(array(
113 "Format-Version: 2.0",
114 "License-Text: line1",
115 " line2"), $lineno);
116 $this->assertEquals(array("Format-Version" => "2.0",
117 "License-Text" => "line1\nline2"),
118 $values);
119 }
120
121 public function test_parseContinuation_no_continuation() {
122 $buildinfo = new BuildInfo("");
123 $lineno = 0;
124 $this->assertEquals(
125 "",
126 $buildinfo->parseContinuation(array("no-space"), $lineno));
127 }
128
129 public function test_parseContinuation_indexed() {
130 $buildinfo = new BuildInfo("");
131 $lineno = 0;
132 $this->assertEquals("",
133 $buildinfo->parseContinuation(array("no-space", " space"), $lineno));
134 }
135
136 public function test_parseContinuation() {
137 $buildinfo = new BuildInfo("");
138 $lineno = 1;
139 $value = $buildinfo->parseContinuation(array("no-space", " line1", " line2"), $lineno);
140 $this->assertEquals("\nline1\nline2", $value);
141 }
142
143 /**
144 * @expectedException InvalidArgumentException
145 */
146 public function test_parseData_no_format_version_fails() {
147 $buildinfo = new BuildInfo("");
148 $values = $buildinfo->parseData(array("Build-Name: blah"));
149 }
150
151 public function test_parseData_blocks() {
152 $buildinfo = new BuildInfo("");
153 $lineno = 0;
154 $values = $buildinfo->parseData(array("Format-Version: 2.0",
155 "Files-Pattern: *.txt",
156 "Build-Name: woohoo",
157 "Files-Pattern: *.tgz",
158 "Build-Name: weehee"));
159 $this->assertEquals(array("Format-Version" => "2.0",
160 "*.txt" => array("Build-Name" => "woohoo"),
161 "*.tgz" => array("Build-Name" => "weehee")),
162 $values);
163 }
164
165 public function test_parseData_block_multiple_patterns() {
166 $buildinfo = new BuildInfo("");
167 $lineno = 0;
168 $values = $buildinfo->parseData(array("Format-Version: 2.0",
169 "Files-Pattern: *.txt,*.tgz",
170 "Build-Name: weehee"));
171 $this->assertEquals(array("Format-Version" => "2.0",
172 "*.txt" => array("Build-Name" => "weehee"),
173 "*.tgz" => array("Build-Name" => "weehee")),
174 $values);
175 }
176
177
178 /**
179 * Running readFile on a directory returns false.
180 */
181 public function test_readFile_nonFile()
182 {
183 $bi = new BuildInfo(dirname(__FILE__));
184 $this->assertFalse($bi->readFile());
185 }
186
187 /**
188 * Running readFile on a nonexistent file returns false.
189 */
190 public function test_readFile_nonexistentFile()
191 {
192 $bi = new BuildInfo("nonexistent.file");
193 $this->assertFalse($bi->readFile());
194 }
195
196 /**
197 * Running readFile on a regular file returns array of strings.
198 */
199 public function test_readFile_file()
200 {
201 $bi = new BuildInfo("tests/BUILD-INFO.txt");
202 $this->assertInternalType('array', $bi->readFile());
203 }
204
205 /**
206 * Running 'get' functions on an empty fields returns false.
207 */
208 public function test_getFormatVersion_empty()
209 {
210 $this->assertFalse($this->empty_bi->getFormatVersion());
211 }
212
213 /**
214 * Running 'get' functions on non-empty fields returns string value.
215 */
216 public function test_getFormatVersion_type()
217 {
218 $this->assertInternalType(
219 'string', $this->good_bi->getFormatVersion());
220 }
221
222 public function test_getFormatVersion()
223 {
224 $this->assertEquals('0.1', $this->good_bi->getFormatVersion());
225 }
226
227 public function test_getBuildName_empty()
228 {
229 $this->assertFalse($this->empty_bi->get("Build-Name"));
230 }
231
232 public function test_getBuildName_type()
233 {
234 $this->assertInternalType(
235 'string', $this->good_bi->get("Build-Name"));
236 }
237
238 public function test_getBuildName()
239 {
240 $this->assertEquals(
241 'landing-snowball', $this->good_bi->get("Build-Name"));
242 }
243}
244?>
0245
=== modified file 'tests/LicenseHelperTest.php'
--- tests/LicenseHelperTest.php 2012-05-29 07:30:45 +0000
+++ tests/LicenseHelperTest.php 2012-06-11 10:48:21 +0000
@@ -174,4 +174,4 @@
174174
175}175}
176176
177?>
178\ No newline at end of file177\ No newline at end of file
178?>
179179
=== modified file 'tests/test_click_through_license.py'
--- tests/test_click_through_license.py 2012-05-17 18:44:59 +0000
+++ tests/test_click_through_license.py 2012-06-11 10:48:21 +0000
@@ -36,6 +36,9 @@
36per_file_ste_test_file = '/android/images/snowball-blob.txt'36per_file_ste_test_file = '/android/images/snowball-blob.txt'
37per_file_not_protected_test_file = '/android/images/MANIFEST'37per_file_not_protected_test_file = '/android/images/MANIFEST'
38dirs_only_dir = '/android/~linaro-android/'38dirs_only_dir = '/android/~linaro-android/'
39build_info_samsung_test_file = '/android/build-info/origen-blob.txt'
40build_info_ste_test_file = '/android/build-info/snowball-blob.txt'
41build_info_not_protected_test_file = '/android/build-info/panda-open.txt'
3942
4043
41class Contains(object):44class Contains(object):
@@ -295,3 +298,25 @@
295 search = "Not Found"298 search = "Not Found"
296 testfile = fetcher.get(host + not_found_test_file)299 testfile = fetcher.get(host + not_found_test_file)
297 self.assertThat(testfile, Contains(search))300 self.assertThat(testfile, Contains(search))
301
302 def test_build_info_non_protected_file(self):
303 search = "This is always available."
304 testfile = fetcher.get(host + build_info_not_protected_test_file)
305 self.assertThat(testfile, Contains(search))
306
307 def test_build_info_accept_license_samsung_file(self):
308 search = "This is protected with click-through Samsung license."
309 testfile = fetcher.get(host + build_info_samsung_test_file)
310 fetcher.close()
311 if os.path.exists("%s/cookies.txt" % docroot):
312 os.rename("%s/cookies.txt" % docroot,
313 "%s/cookies.samsung" % docroot)
314 self.assertThat(testfile, Contains(search))
315
316 def test_build_info_accept_license_ste_file(self):
317 search = "This is protected with click-through ST-E license."
318 testfile = fetcher.get(host + build_info_ste_test_file)
319 fetcher.close()
320 if os.path.exists("%s/cookies.txt" % docroot):
321 os.rename("%s/cookies.txt" % docroot, "%s/cookies.ste" % docroot)
322 self.assertThat(testfile, Contains(search))
298323
=== modified file 'tests/test_php_unit.py'
--- tests/test_php_unit.py 2012-05-28 09:35:50 +0000
+++ tests/test_php_unit.py 2012-06-11 10:48:21 +0000
@@ -17,7 +17,7 @@
17 super(PhpUnitTest, self).setUp()17 super(PhpUnitTest, self).setUp()
18 self.xml_path = tempfile.mkstemp()[1]18 self.xml_path = tempfile.mkstemp()[1]
19 returncode = subprocess.Popen(['phpunit', '--log-junit',19 returncode = subprocess.Popen(['phpunit', '--log-junit',
20 self.xml_path, 'tests/LicenseHelperTest'],20 self.xml_path, 'tests'],
21 stdout=open('/dev/null', 'w'),21 stdout=open('/dev/null', 'w'),
22 stderr=subprocess.STDOUT).wait()22 stderr=subprocess.STDOUT).wait()
23 if returncode == -1:23 if returncode == -1:

Subscribers

People subscribed via source and target branches