secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock(); $this->config = $this->getMockBuilder(IConfig::class)->getMock(); $this->csrfTokenManager = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager') ->disableOriginalConstructor()->getMock(); } protected function tearDown(): void { stream_wrapper_unregister('fakeinput'); parent::tearDown(); } public function testRequestAccessors() { $vars = [ 'get' => ['name' => 'John Q. Public', 'nickname' => 'Joey'], 'method' => 'GET', ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); // Countable $this->assertSame(2, count($request)); // Array access $this->assertSame('Joey', $request['nickname']); // "Magic" accessors $this->assertSame('Joey', $request->{'nickname'}); $this->assertTrue(isset($request['nickname'])); $this->assertTrue(isset($request->{'nickname'})); $this->assertFalse(isset($request->{'flickname'})); // Only testing 'get', but same approach for post, files etc. $this->assertSame('Joey', $request->get['nickname']); // Always returns null if variable not set. $this->assertSame(null, $request->{'flickname'}); } // urlParams has precedence over POST which has precedence over GET public function testPrecedence() { $vars = [ 'get' => ['name' => 'John Q. Public', 'nickname' => 'Joey'], 'post' => ['name' => 'Jane Doe', 'nickname' => 'Janey'], 'urlParams' => ['user' => 'jw', 'name' => 'Johnny Weissmüller'], 'method' => 'GET' ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame(3, count($request)); $this->assertSame('Janey', $request->{'nickname'}); $this->assertSame('Johnny Weissmüller', $request->{'name'}); } public function testImmutableArrayAccess() { $this->expectException(\RuntimeException::class); $vars = [ 'get' => ['name' => 'John Q. Public', 'nickname' => 'Joey'], 'method' => 'GET' ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $request['nickname'] = 'Janey'; } public function testImmutableMagicAccess() { $this->expectException(\RuntimeException::class); $vars = [ 'get' => ['name' => 'John Q. Public', 'nickname' => 'Joey'], 'method' => 'GET' ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $request->{'nickname'} = 'Janey'; } public function testGetTheMethodRight() { $this->expectException(\LogicException::class); $vars = [ 'get' => ['name' => 'John Q. Public', 'nickname' => 'Joey'], 'method' => 'GET', ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $request->post; } public function testTheMethodIsRight() { $vars = [ 'get' => ['name' => 'John Q. Public', 'nickname' => 'Joey'], 'method' => 'GET', ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('GET', $request->method); $result = $request->get; $this->assertSame('John Q. Public', $result['name']); $this->assertSame('Joey', $result['nickname']); } public function testJsonPost() { global $data; $data = '{"name": "John Q. Public", "nickname": "Joey"}'; $vars = [ 'method' => 'POST', 'server' => ['CONTENT_TYPE' => 'application/json; utf-8'] ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('POST', $request->method); $result = $request->post; $this->assertSame('John Q. Public', $result['name']); $this->assertSame('Joey', $result['nickname']); $this->assertSame('Joey', $request->params['nickname']); $this->assertSame('Joey', $request['nickname']); } public function testNotJsonPost() { global $data; $data = 'this is not valid json'; $vars = [ 'method' => 'POST', 'server' => ['CONTENT_TYPE' => 'application/json; utf-8'] ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertEquals('POST', $request->method); $result = $request->post; // ensure there's no error attempting to decode the content } public function testPatch() { global $data; $data = http_build_query(['name' => 'John Q. Public', 'nickname' => 'Joey'], '', '&'); $vars = [ 'method' => 'PATCH', 'server' => ['CONTENT_TYPE' => 'application/x-www-form-urlencoded'], ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('PATCH', $request->method); $result = $request->patch; $this->assertSame('John Q. Public', $result['name']); $this->assertSame('Joey', $result['nickname']); } public function testJsonPatchAndPut() { global $data; // PUT content $data = '{"name": "John Q. Public", "nickname": "Joey"}'; $vars = [ 'method' => 'PUT', 'server' => ['CONTENT_TYPE' => 'application/json; utf-8'], ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('PUT', $request->method); $result = $request->put; $this->assertSame('John Q. Public', $result['name']); $this->assertSame('Joey', $result['nickname']); // PATCH content $data = '{"name": "John Q. Public", "nickname": null}'; $vars = [ 'method' => 'PATCH', 'server' => ['CONTENT_TYPE' => 'application/json; utf-8'], ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('PATCH', $request->method); $result = $request->patch; $this->assertSame('John Q. Public', $result['name']); $this->assertSame(null, $result['nickname']); } public function testPutStream() { global $data; $data = file_get_contents(__DIR__ . '/../../../data/testimage.png'); $vars = [ 'put' => $data, 'method' => 'PUT', 'server' => [ 'CONTENT_TYPE' => 'image/png', 'CONTENT_LENGTH' => (string)strlen($data) ], ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('PUT', $request->method); $resource = $request->put; $contents = stream_get_contents($resource); $this->assertSame($data, $contents); try { $resource = $request->put; } catch(\LogicException $e) { return; } $this->fail('Expected LogicException.'); } public function testSetUrlParameters() { $vars = [ 'post' => [], 'method' => 'POST', 'urlParams' => ['id' => '2'], ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $newParams = ['id' => '3', 'test' => 'test2']; $request->setUrlParameters($newParams); $this->assertSame('test2', $request->getParam('test')); $this->assertEquals('3', $request->getParam('id')); $this->assertEquals('3', $request->getParams()['id']); } public function testGetIdWithModUnique() { $vars = [ 'server' => [ 'UNIQUE_ID' => 'GeneratedUniqueIdByModUnique' ], ]; $request = new Request( $vars, $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('GeneratedUniqueIdByModUnique', $request->getId()); } public function testGetIdWithoutModUnique() { $this->secureRandom->expects($this->once()) ->method('generate') ->with('20') ->willReturn('GeneratedByOwnCloudItself'); $request = new Request( [], $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('GeneratedByOwnCloudItself', $request->getId()); } public function testGetIdWithoutModUniqueStable() { $request = new Request( [], \OC::$server->getSecureRandom(), $this->config, $this->csrfTokenManager, $this->stream ); $firstId = $request->getId(); $secondId = $request->getId(); $this->assertSame($firstId, $secondId); } public function testGetRemoteAddressWithoutTrustedRemote() { $this->config ->expects($this->once()) ->method('getSystemValue') ->with('trusted_proxies') ->willReturn([]); $request = new Request( [ 'server' => [ 'REMOTE_ADDR' => '10.0.0.2', 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' ], ], $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('10.0.0.2', $request->getRemoteAddress()); } public function testGetRemoteAddressWithNoTrustedHeader() { $this->config ->expects($this->at(0)) ->method('getSystemValue') ->with('trusted_proxies') ->willReturn(['10.0.0.2']); $this->config ->expects($this->at(1)) ->method('getSystemValue') ->with('forwarded_for_headers') ->willReturn([]); $request = new Request( [ 'server' => [ 'REMOTE_ADDR' => '10.0.0.2', 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' ], ], $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('10.0.0.2', $request->getRemoteAddress()); } public function testGetRemoteAddressWithSingleTrustedRemote() { $this->config ->expects($this->at(0)) ->method('getSystemValue') ->with('trusted_proxies') ->willReturn(['10.0.0.2']); $this->config ->expects($this->at(1)) ->method('getSystemValue') ->with('forwarded_for_headers') ->willReturn(['HTTP_X_FORWARDED']); $request = new Request( [ 'server' => [ 'REMOTE_ADDR' => '10.0.0.2', 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' ], ], $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('10.4.0.5', $request->getRemoteAddress()); } public function testGetRemoteAddressIPv6WithSingleTrustedRemote() { $this->config ->expects($this->at(0)) ->method('getSystemValue') ->with('trusted_proxies') ->willReturn(['2001:db8:85a3:8d3:1319:8a2e:370:7348']); $this->config ->expects($this->at(1)) ->method('getSystemValue') ->with('forwarded_for_headers') ->willReturn(['HTTP_X_FORWARDED']); $request = new Request( [ 'server' => [ 'REMOTE_ADDR' => '2001:db8:85a3:8d3:1319:8a2e:370:7348', 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' ], ], $this->secureRandom, $this->config, $this->csrfTokenManager, $this->stream ); $this->assertSame('10.4.0.5', $request->getRemoteAddress()); } public function testGetRemoteAddressVerifyPriorityHeader() { $this->config ->expects($this->at(0)) ->method('getSystemValue') ->with('trusted_proxies') ->willReturn(['10.0.0.2']); $this->config ->expects($this->at(1)) ->method('getSystemValue') ->with('forwarded_for_headers') ->willReturn([ 'HTTP_CLIENT_IP', 'H
$(document).ready(function() {
	
	// link demos
	
	$(".demoflow div.wrapper").click(function() {
		
		var demo = $(this).children('img').attr('_demo');
		
		if (demo) {
			location.href = '/repository/real-world/' + demo;
		}else {
			//alert('Under construction!');
		}
		
	});
	
	if ($("div.demoflow").size()) {
		
		var inst = new $.ui.carousel($("div.demoflow")[0], { height: 200, width: 310 });

		$("div.demoflow-button-left, div.demoflow-button-right").bind("mousedown", function() {
			var right = this.className.indexOf("right") == -1;
			if(inst.autoRotator) window.clearInterval(inst.autoRotator);
			inst.timer = window.setInterval(function() { inst.rotate(right ? "right" : null); }, 13);
		})
		.bind("mouseup", function() {
			window.clearInterval(inst.timer);
		});
		
		$('.demoflow div.shadow').hover(function() {
			this._lastopacity = $(this).css('opacity');
			$(this).stop().animate({opacity: 0 }, 300); 
		}, function() {
			$(this).stop().animate({opacity: this._lastopacity }, 300);
		});
		

		window.setTimeout(function() {
			inst.element.animate({ opacity: 1 },2000); inst.rotate(0,2000,0.45);
			window.setTimeout(function() {
				inst.autoRotator = window.setInterval(function() { inst.rotate(0,2000,0.45); },5000);
			},3000);
		},0);

	}

	$('a').click(function(){
		this.blur();
	});
	
	// smooth hover effects by DragonInteractive
	var hover = hoverEffects();
	hover.init();

});
	
	$.ui.carousel = function(element, options) {

		this.element = $(element);
		this.options = $.extend({}, options);
		var self = this;

		$.extend(this, {
			start: Math.PI/2,
			step: 2*Math.PI/$("> *", this.element).length,
			radiusX: 400,
			radiusY: -45,
			paddingX: this.element.outerWidth() / 2,
			paddingY: this.element.outerHeight() / 2
		});
		
		$("> *", this.element).css({ position: "absolute", top: 0, left: 0, zIndex: 1 });
		this.rotate();
		this.rotate("right");
		
		this.element.parent().bind("mousewheel", function(event ,delta) {
			if(self.autoRotator) window.clearInterval(self.autoRotator);
			self.rotate(delta < 0 ? "right" : "left");
			return false;
		});
		
	};
	
	$.ui.carousel.prototype.rotate = function(d,ani,speed) {

		this.start = this.start + (d == "right" ? -(speed || 0.03) : (speed || 0.03));
		var o = this.options;
		var self = this;
		
		setTimeout(function(){
			$("> *", self.element).each(function(i) {
				var angle = self.start + i * self.step;
				var x = self.radiusX * Math.cos(angle);
				var y = self.radiusY * Math.sin(angle);
				var _self = this;
				
				var width = o.width * ((self.radiusY+y) / (2 * self.radiusY));
				width = (width * width * width) / (o.width * o.width); //This makes the pieces smaller
				var height = parseInt(width * o.height / o.width);
	
				//This is highly custom - it will hide the elements at the back
				$(_self).css({ visibility: height < 30 ? "hidden" : "visible" });
				if(height < 30 && !ani) return; //This imrpoves the speed, but cannot be used with animation
				
				
				if(ani) {
					$(_self).animate({
						top: Math.round(self.paddingY + y - height/2) + "px",
						left: Math.round(self.paddingX + x - width/2) + "px",
						width: Math.round(width) + "px",
						height: Math.round(height) + "px"
					},{ duration: ani, easing: "easeOutQuad" });
				$(_self).css({ zIndex: Math.round(parseInt(100 * (self.radiusY+y) / (2 * self.radiusY))) });
				} else {
					$(_self).css({
						top: self.paddingY + y - height/2 + "px",
						left: self.paddingX + x - width/2 + "px",
						width: width + "px",
						height: height + "px",
						zIndex: parseInt(100 * (self.radiusY+y) / (2 * self.radiusY))
					});
				}

				$("div.shadow",_self).css({ opacity: 1 - (width / o.width) });
				
			});
		}, 0);
	}


/**
 * All credit here goes to DragonInteractive and Yuri Vishnevsky
 */
var hoverEffects = function() {
	var me = this;
	var args = arguments;
	var self = {
		c: {
			navItems: '.download .click-to-download, #launch-pad .launch-pad-button, div.demoflow-button-left, div.demoflow-button-right',
			navSpeed: ($.browser.safari ? 600: 350),
			snOpeningSpeed: ($.browser.safari ? 400: 250),
			snOpeningTimeout: 150,
			snClosingSpeed: function() {
				if (self.subnavHovered()) return 123450;
				return 150
			},
			snClosingTimeout: 700
		},
		init: function() {
			//$('.bg', this.c.navItems).css({
			//	'opacity': 0
			//});
			this.initHoverFades()
		},
		subnavHovered: function() {
			var hovered = false;
			$(self.c.navItems).each(function() {
				if (this.hovered) hovered = true
			});
			return hovered
		},
		initHoverFades: function() {
			//$('#navigation .bg').css('opacity', 0);
			$(self.c.navItems).hover(function() {
				self.fadeNavIn.apply(this)
			},
			function() {
				var el = this;
				setTimeout(function() {
					if (!el.open) self.fadeNavOut.apply(el)
				},
				10)
			})
		},
		fadeNavIn: function() {
			$('.bg', this).stop().animate({
				'opacity': 1
			},
			self.c.navSpeed)
		},
		fadeNavOut: function() {
			$('.bg', this).stop().animate({
				'opacity': 0
			},
			self.c.navSpeed)
		},
		initSubmenus: function() {
			$(this.c.navItems).hover(function() {
				$(self.c.navItems).not(this).each(function() {
					self.fadeNavOut.apply(this);
				});
				this.hovered = true;
				var el = this;
				self.fadeNavIn.apply(el);
			},
			function() {
				this.hovered = false;
				var el = this;
				if (!el.open) self.fadeNavOut.apply(el);
			})
		}
	};
	
	return self;
};