Completed
Push — master ( d81f63...df8fd4 )
by Damian
10:18
created
code/IFramePage.php 1 patch
Indentation   +117 added lines, -117 removed lines patch added patch discarded remove patch
@@ -6,126 +6,126 @@
 block discarded – undo
6 6
 
7 7
 class IFramePage extends Page
8 8
 {
9
-    public static $db = array(
10
-        'IFrameURL' => 'Text',
11
-        'AutoHeight' => 'Boolean(1)',
12
-        'AutoWidth' => 'Boolean(1)',
13
-        'FixedHeight' => 'Int(500)',
14
-        'FixedWidth' => 'Int(0)',
15
-        'AlternateContent' => 'HTMLText',
16
-        'BottomContent' => 'HTMLText',
17
-        'ForceProtocol' => 'Varchar',
18
-    );
19
-
20
-    public static $defaults = array(
21
-        'AutoHeight' => '1',
22
-        'AutoWidth' => '1',
23
-        'FixedHeight' => '500',
24
-        'FixedWidth' => '0'
25
-    );
26
-
27
-    public static $description = 'Embeds an iframe into the body of the page.';
9
+	public static $db = array(
10
+		'IFrameURL' => 'Text',
11
+		'AutoHeight' => 'Boolean(1)',
12
+		'AutoWidth' => 'Boolean(1)',
13
+		'FixedHeight' => 'Int(500)',
14
+		'FixedWidth' => 'Int(0)',
15
+		'AlternateContent' => 'HTMLText',
16
+		'BottomContent' => 'HTMLText',
17
+		'ForceProtocol' => 'Varchar',
18
+	);
19
+
20
+	public static $defaults = array(
21
+		'AutoHeight' => '1',
22
+		'AutoWidth' => '1',
23
+		'FixedHeight' => '500',
24
+		'FixedWidth' => '0'
25
+	);
26
+
27
+	public static $description = 'Embeds an iframe into the body of the page.';
28 28
     
29
-    public function getCMSFields()
30
-    {
31
-        $fields = parent::getCMSFields();
32
-
33
-        $fields->removeFieldFromTab('Root.Main', 'Content');
34
-        $fields->addFieldToTab('Root.Main', $url = new TextField('IFrameURL', 'Iframe URL'), 'Metadata');
35
-        $url->setRightTitle('Can be absolute (<em>http://silverstripe.com</em>) or relative to this site (<em>about-us</em>).');
36
-        $fields->addFieldToTab(
37
-            'Root.Main',
38
-            DropdownField::create('ForceProtocol', 'Force protocol?')
39
-                ->setSource(array('http://' => 'http://', 'https://' => 'https://'))
40
-                ->setEmptyString('')
41
-                ->setDescription('Avoids mixed content warnings when iframe content is just available under a specific protocol'),
42
-            'Metadata'
43
-        );
44
-        $fields->addFieldToTab('Root.Main', new CheckboxField('AutoHeight', 'Auto height (only works with same domain URLs)'), 'Metadata');
45
-        $fields->addFieldToTab('Root.Main', new CheckboxField('AutoWidth', 'Auto width (100% of the available space)'), 'Metadata');
46
-        $fields->addFieldToTab('Root.Main', new NumericField('FixedHeight', 'Fixed height (in pixels)'), 'Metadata');
47
-        $fields->addFieldToTab('Root.Main', new NumericField('FixedWidth', 'Fixed width (in pixels)'), 'Metadata');
48
-        $fields->addFieldToTab('Root.Main', new HtmlEditorField('Content', 'Content (appears above iframe)'), 'Metadata');
49
-        $fields->addFieldToTab('Root.Main', new HtmlEditorField('BottomContent', 'Content (appears below iframe)'), 'Metadata');
50
-        $fields->addFieldToTab('Root.Main', new HtmlEditorField('AlternateContent', 'Alternate Content (appears when user has iframes disabled)'), 'Metadata');
51
-
52
-        return $fields;
53
-    }
54
-
55
-    /**
56
-     * Compute class from the size parameters.
57
-     */
58
-    public function getClass()
59
-    {
60
-        $class = '';
61
-        if ($this->AutoHeight) {
62
-            $class .= 'iframepage-height-auto';
63
-        }
64
-
65
-        return $class;
66
-    }
67
-
68
-    /**
69
-     * Compute style from the size parameters.
70
-     */
71
-    public function getStyle()
72
-    {
73
-        $style = '';
74
-
75
-        // Always add fixed height as a fallback if autosetting or JS fails.
76
-        $height = $this->FixedHeight;
77
-        if (!$height) {
78
-            $height = 800;
79
-        }
80
-        $style .= "height: {$height}px; ";
81
-
82
-        if ($this->AutoWidth) {
83
-            $style .= "width: 100%; ";
84
-        } elseif ($this->FixedWidth) {
85
-            $style .= "width: {$this->FixedWidth}px; ";
86
-        }
87
-
88
-        return $style;
89
-    }
90
-
91
-    /**
92
-     * Ensure that the IFrameURL is a valid url and prevents XSS
93
-     * 
94
-     * @throws ValidationException
95
-     * @return ValidationResult
96
-     */
97
-    public function validate()
98
-    {
99
-        $result = parent::validate();
100
-
101
-        //whitelist allowed URL schemes
102
-        $allowed_schemes = array('http', 'https');
103
-        if ($matches = parse_url($this->IFrameURL)) {
104
-            if (isset($matches['scheme']) && !in_array($matches['scheme'], $allowed_schemes)) {
105
-                $result->error(_t('IFramePage.VALIDATION.BANNEDURLSCHEME', "This URL scheme is not allowed."));
106
-            }
107
-        }
108
-
109
-        return $result;
110
-    }
29
+	public function getCMSFields()
30
+	{
31
+		$fields = parent::getCMSFields();
32
+
33
+		$fields->removeFieldFromTab('Root.Main', 'Content');
34
+		$fields->addFieldToTab('Root.Main', $url = new TextField('IFrameURL', 'Iframe URL'), 'Metadata');
35
+		$url->setRightTitle('Can be absolute (<em>http://silverstripe.com</em>) or relative to this site (<em>about-us</em>).');
36
+		$fields->addFieldToTab(
37
+			'Root.Main',
38
+			DropdownField::create('ForceProtocol', 'Force protocol?')
39
+				->setSource(array('http://' => 'http://', 'https://' => 'https://'))
40
+				->setEmptyString('')
41
+				->setDescription('Avoids mixed content warnings when iframe content is just available under a specific protocol'),
42
+			'Metadata'
43
+		);
44
+		$fields->addFieldToTab('Root.Main', new CheckboxField('AutoHeight', 'Auto height (only works with same domain URLs)'), 'Metadata');
45
+		$fields->addFieldToTab('Root.Main', new CheckboxField('AutoWidth', 'Auto width (100% of the available space)'), 'Metadata');
46
+		$fields->addFieldToTab('Root.Main', new NumericField('FixedHeight', 'Fixed height (in pixels)'), 'Metadata');
47
+		$fields->addFieldToTab('Root.Main', new NumericField('FixedWidth', 'Fixed width (in pixels)'), 'Metadata');
48
+		$fields->addFieldToTab('Root.Main', new HtmlEditorField('Content', 'Content (appears above iframe)'), 'Metadata');
49
+		$fields->addFieldToTab('Root.Main', new HtmlEditorField('BottomContent', 'Content (appears below iframe)'), 'Metadata');
50
+		$fields->addFieldToTab('Root.Main', new HtmlEditorField('AlternateContent', 'Alternate Content (appears when user has iframes disabled)'), 'Metadata');
51
+
52
+		return $fields;
53
+	}
54
+
55
+	/**
56
+	 * Compute class from the size parameters.
57
+	 */
58
+	public function getClass()
59
+	{
60
+		$class = '';
61
+		if ($this->AutoHeight) {
62
+			$class .= 'iframepage-height-auto';
63
+		}
64
+
65
+		return $class;
66
+	}
67
+
68
+	/**
69
+	 * Compute style from the size parameters.
70
+	 */
71
+	public function getStyle()
72
+	{
73
+		$style = '';
74
+
75
+		// Always add fixed height as a fallback if autosetting or JS fails.
76
+		$height = $this->FixedHeight;
77
+		if (!$height) {
78
+			$height = 800;
79
+		}
80
+		$style .= "height: {$height}px; ";
81
+
82
+		if ($this->AutoWidth) {
83
+			$style .= "width: 100%; ";
84
+		} elseif ($this->FixedWidth) {
85
+			$style .= "width: {$this->FixedWidth}px; ";
86
+		}
87
+
88
+		return $style;
89
+	}
90
+
91
+	/**
92
+	 * Ensure that the IFrameURL is a valid url and prevents XSS
93
+	 * 
94
+	 * @throws ValidationException
95
+	 * @return ValidationResult
96
+	 */
97
+	public function validate()
98
+	{
99
+		$result = parent::validate();
100
+
101
+		//whitelist allowed URL schemes
102
+		$allowed_schemes = array('http', 'https');
103
+		if ($matches = parse_url($this->IFrameURL)) {
104
+			if (isset($matches['scheme']) && !in_array($matches['scheme'], $allowed_schemes)) {
105
+				$result->error(_t('IFramePage.VALIDATION.BANNEDURLSCHEME', "This URL scheme is not allowed."));
106
+			}
107
+		}
108
+
109
+		return $result;
110
+	}
111 111
 }
112 112
 
113 113
 class IFramePage_Controller extends Page_Controller
114 114
 {
115
-    public function init()
116
-    {
117
-        parent::init();
118
-
119
-        if ($this->ForceProtocol) {
120
-            if ($this->ForceProtocol == 'http://' && Director::protocol() != 'http://') {
121
-                return $this->redirect(preg_replace('#https://#', 'http://', $this->AbsoluteLink()));
122
-            } elseif ($this->ForceProtocol == 'https://' && Director::protocol() != 'https://') {
123
-                return $this->redirect(preg_replace('#http://#', 'https://', $this->AbsoluteLink()));
124
-            }
125
-        }
126
-
127
-        if ($this->IFrameURL) {
128
-            Requirements::javascript('iframe/javascript/iframe_page.js');
129
-        }
130
-    }
115
+	public function init()
116
+	{
117
+		parent::init();
118
+
119
+		if ($this->ForceProtocol) {
120
+			if ($this->ForceProtocol == 'http://' && Director::protocol() != 'http://') {
121
+				return $this->redirect(preg_replace('#https://#', 'http://', $this->AbsoluteLink()));
122
+			} elseif ($this->ForceProtocol == 'https://' && Director::protocol() != 'https://') {
123
+				return $this->redirect(preg_replace('#http://#', 'https://', $this->AbsoluteLink()));
124
+			}
125
+		}
126
+
127
+		if ($this->IFrameURL) {
128
+			Requirements::javascript('iframe/javascript/iframe_page.js');
129
+		}
130
+	}
131 131
 }
Please login to merge, or discard this patch.
tests/IFramePageTest.php 1 patch
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -2,138 +2,138 @@
 block discarded – undo
2 2
 
3 3
 class IFramePageTest extends SapphireTest
4 4
 {
5
-    public function setUp()
6
-    {
7
-        parent::setUp();
8
-        Config::nest();
9
-    }
10
-
11
-    public function tearDown()
12
-    {
13
-        Config::unnest();
14
-        parent::tearDown();
15
-    }
16
-
17
-    public function testGetClass()
18
-    {
19
-        $iframe = new IFramePage();
20
-        $iframe->AutoHeight = 1;
21
-        $iframe->getClass();
22
-
23
-        $this->assertContains('iframepage-height-auto', $iframe->getClass());
24
-
25
-        $iframe->AutoHeight = 0;
26
-        $iframe->getClass();
27
-
28
-        $this->assertNotContains('iframepage-height-auto', $iframe->getClass());
29
-    }
30
-
31
-    public function testGetStyle()
32
-    {
33
-        $iframe = new IFramePage();
34
-
35
-        $iframe->FixedHeight = 0;
36
-        $iframe->getStyle();
37
-        $this->assertContains('height: 800px', $iframe->getStyle(), 'Height defaults to 800 if not set.');
38
-
39
-        $iframe->FixedHeight = 100;
40
-        $iframe->getStyle();
41
-        $this->assertContains('height: 100px', $iframe->getStyle(), 'Fixed height is settable');
42
-
43
-        $iframe->AutoWidth = 1;
44
-        $iframe->FixedWidth = '200';
45
-        $this->assertContains('width: 100%', $iframe->getStyle(), 'Auto width overrides fixed width');
46
-
47
-        $iframe->AutoWidth = 0;
48
-        $iframe->FixedWidth = '200';
49
-        $this->assertContains('width: 200px', $iframe->getStyle(), 'Fixed width is settable');
50
-    }
51
-
52
-    public function testAllowedUrls()
53
-    {
54
-        $iframe = new IFramePage();
55
-
56
-        $tests = array(
57
-            'allowed' => array(
58
-                'http://anything',
59
-                'https://anything',
60
-                'page',
61
-                'sub-page/link',
62
-                'page/link',
63
-                'page.html',
64
-                'page.htm',
65
-                'page.phpissoawesomewhywouldiuseanythingelse',
66
-                '//url.com/page',
67
-                '/root/page/link',
68
-                'http://intranet:8888',
69
-                'http://javascript:8080',
70
-                'http://username:password@hostname/path?arg=value#anchor'
71
-            ),
72
-            'banned' => array(
73
-                'javascript:alert',
74
-                'tel:0210001234',
75
-                'ftp://url',
76
-                'ssh://1.2.3.4',
77
-                'ssh://url.com/page'
78
-            )
79
-        );
80
-
81
-        foreach ($tests['allowed'] as $url) {
82
-            $iframe->IFrameURL = $url;
83
-            $iframe->write();
84
-            $this->assertContains($iframe->IFrameURL, $url);
85
-        }
86
-
87
-        foreach ($tests['banned'] as $url) {
88
-            $iframe->IFrameURL = $url;
89
-            $this->setExpectedException('ValidationException');
90
-            $iframe->write();
91
-        }
92
-    }
93
-
94
-    public function testForceProtocol()
95
-    {
96
-        $origServer = $_SERVER;
97
-
98
-        $page = new IFramePage();
99
-        $page->URLSegment = 'iframe';
100
-        $page->IFrameURL = 'http://target.com';
101
-
102
-        Config::inst()->update('Director', 'alternate_protocol', 'http');
103
-        Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
104
-        $page->ForceProtocol = '';
105
-        $controller = new IFramePage_Controller($page);
106
-        $response = $controller->init();
107
-        $this->assertNull($response);
108
-
109
-        Config::inst()->update('Director', 'alternate_protocol', 'https');
110
-        Config::inst()->update('Director', 'alternate_base_url', 'https://host.com');
111
-        $page->ForceProtocol = '';
112
-        $controller = new IFramePage_Controller($page);
113
-        $response = $controller->init();
114
-        $this->assertNull($response);
115
-
116
-        Config::inst()->update('Director', 'alternate_protocol', 'http');
117
-        Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
118
-        $page->ForceProtocol = 'http://';
119
-        $controller = new IFramePage_Controller($page);
120
-        $response = $controller->init();
121
-        $this->assertNull($response);
122
-
123
-        Config::inst()->update('Director', 'alternate_protocol', 'http');
124
-        Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
125
-        $page->ForceProtocol = 'https://';
126
-        $controller = new IFramePage_Controller($page);
127
-        $response = $controller->init();
128
-        $this->assertEquals($response->getHeader('Location'), 'https://host.com/iframe/');
129
-
130
-        Config::inst()->update('Director', 'alternate_protocol', 'https');
131
-        Config::inst()->update('Director', 'alternate_base_url', 'https://host.com');
132
-        $page->ForceProtocol = 'http://';
133
-        $controller = new IFramePage_Controller($page);
134
-        $response = $controller->init();
135
-        $this->assertEquals($response->getHeader('Location'), 'http://host.com/iframe/');
136
-
137
-        $_SERVER = $origServer;
138
-    }
5
+	public function setUp()
6
+	{
7
+		parent::setUp();
8
+		Config::nest();
9
+	}
10
+
11
+	public function tearDown()
12
+	{
13
+		Config::unnest();
14
+		parent::tearDown();
15
+	}
16
+
17
+	public function testGetClass()
18
+	{
19
+		$iframe = new IFramePage();
20
+		$iframe->AutoHeight = 1;
21
+		$iframe->getClass();
22
+
23
+		$this->assertContains('iframepage-height-auto', $iframe->getClass());
24
+
25
+		$iframe->AutoHeight = 0;
26
+		$iframe->getClass();
27
+
28
+		$this->assertNotContains('iframepage-height-auto', $iframe->getClass());
29
+	}
30
+
31
+	public function testGetStyle()
32
+	{
33
+		$iframe = new IFramePage();
34
+
35
+		$iframe->FixedHeight = 0;
36
+		$iframe->getStyle();
37
+		$this->assertContains('height: 800px', $iframe->getStyle(), 'Height defaults to 800 if not set.');
38
+
39
+		$iframe->FixedHeight = 100;
40
+		$iframe->getStyle();
41
+		$this->assertContains('height: 100px', $iframe->getStyle(), 'Fixed height is settable');
42
+
43
+		$iframe->AutoWidth = 1;
44
+		$iframe->FixedWidth = '200';
45
+		$this->assertContains('width: 100%', $iframe->getStyle(), 'Auto width overrides fixed width');
46
+
47
+		$iframe->AutoWidth = 0;
48
+		$iframe->FixedWidth = '200';
49
+		$this->assertContains('width: 200px', $iframe->getStyle(), 'Fixed width is settable');
50
+	}
51
+
52
+	public function testAllowedUrls()
53
+	{
54
+		$iframe = new IFramePage();
55
+
56
+		$tests = array(
57
+			'allowed' => array(
58
+				'http://anything',
59
+				'https://anything',
60
+				'page',
61
+				'sub-page/link',
62
+				'page/link',
63
+				'page.html',
64
+				'page.htm',
65
+				'page.phpissoawesomewhywouldiuseanythingelse',
66
+				'//url.com/page',
67
+				'/root/page/link',
68
+				'http://intranet:8888',
69
+				'http://javascript:8080',
70
+				'http://username:password@hostname/path?arg=value#anchor'
71
+			),
72
+			'banned' => array(
73
+				'javascript:alert',
74
+				'tel:0210001234',
75
+				'ftp://url',
76
+				'ssh://1.2.3.4',
77
+				'ssh://url.com/page'
78
+			)
79
+		);
80
+
81
+		foreach ($tests['allowed'] as $url) {
82
+			$iframe->IFrameURL = $url;
83
+			$iframe->write();
84
+			$this->assertContains($iframe->IFrameURL, $url);
85
+		}
86
+
87
+		foreach ($tests['banned'] as $url) {
88
+			$iframe->IFrameURL = $url;
89
+			$this->setExpectedException('ValidationException');
90
+			$iframe->write();
91
+		}
92
+	}
93
+
94
+	public function testForceProtocol()
95
+	{
96
+		$origServer = $_SERVER;
97
+
98
+		$page = new IFramePage();
99
+		$page->URLSegment = 'iframe';
100
+		$page->IFrameURL = 'http://target.com';
101
+
102
+		Config::inst()->update('Director', 'alternate_protocol', 'http');
103
+		Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
104
+		$page->ForceProtocol = '';
105
+		$controller = new IFramePage_Controller($page);
106
+		$response = $controller->init();
107
+		$this->assertNull($response);
108
+
109
+		Config::inst()->update('Director', 'alternate_protocol', 'https');
110
+		Config::inst()->update('Director', 'alternate_base_url', 'https://host.com');
111
+		$page->ForceProtocol = '';
112
+		$controller = new IFramePage_Controller($page);
113
+		$response = $controller->init();
114
+		$this->assertNull($response);
115
+
116
+		Config::inst()->update('Director', 'alternate_protocol', 'http');
117
+		Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
118
+		$page->ForceProtocol = 'http://';
119
+		$controller = new IFramePage_Controller($page);
120
+		$response = $controller->init();
121
+		$this->assertNull($response);
122
+
123
+		Config::inst()->update('Director', 'alternate_protocol', 'http');
124
+		Config::inst()->update('Director', 'alternate_base_url', 'http://host.com');
125
+		$page->ForceProtocol = 'https://';
126
+		$controller = new IFramePage_Controller($page);
127
+		$response = $controller->init();
128
+		$this->assertEquals($response->getHeader('Location'), 'https://host.com/iframe/');
129
+
130
+		Config::inst()->update('Director', 'alternate_protocol', 'https');
131
+		Config::inst()->update('Director', 'alternate_base_url', 'https://host.com');
132
+		$page->ForceProtocol = 'http://';
133
+		$controller = new IFramePage_Controller($page);
134
+		$response = $controller->init();
135
+		$this->assertEquals($response->getHeader('Location'), 'http://host.com/iframe/');
136
+
137
+		$_SERVER = $origServer;
138
+	}
139 139
 }
Please login to merge, or discard this patch.