summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/address-book/protected/application.xml12
-rw-r--r--demos/address-book/protected/pages/AddressProvider.php25
-rw-r--r--demos/address-book/protected/pages/Home.page15
-rw-r--r--demos/address-book/protected/pages/flex/bin/flex_address_book.swfbin300237 -> 307529 bytes
-rw-r--r--demos/address-book/protected/pages/flex/flex_address_book.mxml88
-rw-r--r--framework/3rdParty/WsdlGen/Wsdl.php2
-rw-r--r--framework/Web/Services/TSoapService.php82
7 files changed, 176 insertions, 48 deletions
diff --git a/demos/address-book/protected/application.xml b/demos/address-book/protected/application.xml
index 8e87be8c..8b68fe8f 100644
--- a/demos/address-book/protected/application.xml
+++ b/demos/address-book/protected/application.xml
@@ -3,8 +3,9 @@
<paths>
<using namespace="System.Data.*" />
+ <using namespace="System.Security.*" />
<using namespace="System.Data.ActiveRecord.*" />
- <using namespace="System.Web.Services.TSoapService" />
+ <using namespace="System.Web.Services.*" />
</paths>
<modules>
@@ -12,6 +13,14 @@
<module id="sqlite-db" class="TActiveRecordConfig">
<database ConnectionString="sqlite:./protected/pages/sqlite.db" />
</module>
+
+ <!-- authentication and authorization -->
+ <module id="users" class="TUserManager" PasswordMode="Clear">
+ <user name="demo" password="demo" />
+ <user name="admin" password="admin" />
+ </module>
+ <module id="auth" class="TAuthManager" UserManager="users" LoginPage="Login" />
+
</modules>
<services>
@@ -21,6 +30,7 @@
provider="Application.pages.AddressProvider"
ClassMaps="AddressRecord" />
</service>
+
</services>
</application> \ No newline at end of file
diff --git a/demos/address-book/protected/pages/AddressProvider.php b/demos/address-book/protected/pages/AddressProvider.php
index bbfedd1b..ae0b369f 100644
--- a/demos/address-book/protected/pages/AddressProvider.php
+++ b/demos/address-book/protected/pages/AddressProvider.php
@@ -6,9 +6,31 @@ Prado::using('Application.pages.AddressRecord');
* @version $Id$
* @since 3.1
*/
-class AddressProvider
+class AddressProvider extends TApplicationComponent
{
/**
+ * @throws exception if not logged in
+ */
+ public function __construct($server)
+ {
+ $authMethods = $server->getRequestedMethod()!=='login';
+ $guestUser = $this->User ? $this->User->IsGuest : true;
+ if($authMethods && $guestUser)
+ throw new TException('authentication required');
+ }
+
+ /**
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ * @soapmethod
+ */
+ public function login($username, $password)
+ {
+ return $this->Application->Modules['auth']->login($username, $password);
+ }
+
+ /**
* @return AddressRecord[]
* @soapmethod
*/
@@ -17,7 +39,6 @@ class AddressProvider
return AddressRecord::finder()->findAll();
}
-
/**
* Update address if $data->id > 0, otherwise add new address.
* @param AddressRecord $data
diff --git a/demos/address-book/protected/pages/Home.page b/demos/address-book/protected/pages/Home.page
index 801267e7..1489cf86 100644
--- a/demos/address-book/protected/pages/Home.page
+++ b/demos/address-book/protected/pages/Home.page
@@ -2,24 +2,15 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Prado Address Book</title>
- <style type="text/css">
- /*<![CDATA[*/
- body
- {
- margin:0; padding: 0;
- }
- /*]]>*/
- </style>
</head>
<body>
-
-<div style="margin: 5em auto">
+<h1>Prado + Flex + Soap Demo</h1>
+<h3>Flash player version 9 or greater is required.</h3>
+<p>Username/password: demo/demo </p>
<com:Application.pages.FlexApp
BinDirectory=<%~ flex/bin %>
AppName="flex_address_book"
Parameters.wsdl="<%= $this->Request->constructUrl('soap', 'address-book.wsdl') %>"
Width="100%" Height="300"/>
-</div>
-
</body>
</html> \ No newline at end of file
diff --git a/demos/address-book/protected/pages/flex/bin/flex_address_book.swf b/demos/address-book/protected/pages/flex/bin/flex_address_book.swf
index 9c3e63ef..03e29cf8 100644
--- a/demos/address-book/protected/pages/flex/bin/flex_address_book.swf
+++ b/demos/address-book/protected/pages/flex/bin/flex_address_book.swf
Binary files differ
diff --git a/demos/address-book/protected/pages/flex/flex_address_book.mxml b/demos/address-book/protected/pages/flex/flex_address_book.mxml
index d6db809a..eac50fe7 100644
--- a/demos/address-book/protected/pages/flex/flex_address_book.mxml
+++ b/demos/address-book/protected/pages/flex/flex_address_book.mxml
@@ -10,10 +10,27 @@
backgroundGradientColors="0"
layout="vertical" creationComplete="initApp()">
<mx:states>
- <mx:State name="details">
+ <mx:State name="grid">
+ <mx:RemoveChild target="{form1}"/>
+ <mx:AddChild relativeTo="{panel1}" position="lastChild">
+ <mx:HBox id="hbox1">
+ <mx:DataGrid id="list1" dataProvider="{addrSrv.getAllAddress.lastResult}"
+ width="350" click="currentState='details'">
+ <mx:columns>
+ <mx:DataGridColumn headerText="Name" width="175" dataField="username"/>
+ <mx:DataGridColumn headerText="Phone" dataField="phone"/>
+ </mx:columns>
+ </mx:DataGrid>
+ </mx:HBox>
+ </mx:AddChild>
+ <mx:SetProperty target="{button2}" name="visible" value="true"/>
+ <mx:SetProperty target="{button3}" name="visible" value="true"/>
+ <mx:SetProperty target="{controlbar1}" name="height"/>
+ </mx:State>
+ <mx:State name="details" basedOn="grid">
<mx:AddChild relativeTo="{hbox1}" position="lastChild">
<mx:Form>
- <mx:FormItem label="Username:">
+ <mx:FormItem label="Name:">
<mx:TextInput id="_username" text="{list1.selectedItem.username}"/>
</mx:FormItem>
<mx:FormItem label="Phone:">
@@ -28,10 +45,15 @@
<mx:PhoneNumberValidator id="val1" source="{_phone}" property="text" />
<mx:StringValidator id="val2" source="{_username}" property="text"
minLength="3" maxLength="20" />
+
+ <mx:Validator id="val3" source="{login_name}" property="text" />
+ <mx:Validator id="val4" source="{login_pass}" property="text" />
+ <mx:Validator id="val5" requiredFieldError="Username and password did not match!" />
<mx:WebService id="addrSrv" fault="dataError(event)">
<mx:operation name="saveAddress" result="addrSrv.getAllAddress()" />
<mx:operation name="deleteAddress" result="addrSrv.getAllAddress()" />
+ <mx:operation name="login" result="loginReturned(event)" />
</mx:WebService>
<mx:Script>
@@ -49,7 +71,6 @@
private function initApp():void
{
addrSrv.loadWSDL(getAddressBookWsdl());
- addrSrv.getAllAddress();
}
private function getAddressBookWsdl():String
@@ -75,31 +96,62 @@
data.username = _username.text;
data.phone = _phone.text;
addrSrv.saveAddress(data);
- currentState='';
+ currentState='grid';
}
}
private function doDelete():void
{
addrSrv.deleteAddress(list1.selectedItem.id);
- currentState='';
+ currentState='grid';
+ }
+
+ private function doLogin():void
+ {
+ if(Validator.validateAll([val3, val4]).length == 0)
+ {
+ addrSrv.login(login_name.text, login_pass.text);
+ login_name.enabled=false;
+ login_pass.enabled=false;
+ progress1.visible=true;
+ }
+ }
+
+ private function loginReturned(event:ResultEvent):void
+ {
+ if(!event.result)
+ {
+ login_name.enabled=true;
+ login_pass.enabled=true;
+ progress1.visible=false;
+ Alert.show("Username and password did not match!", "Login Error");
+ }
+ else
+ {
+ addrSrv.getAllAddress();
+ currentState='grid';
+ }
}
]]>
</mx:Script>
-
-
+
<mx:Panel layout="vertical" title="Prado Address Book" id="panel1" resizeEffect="Resize">
- <mx:HBox id="hbox1">
- <mx:DataGrid id="list1" dataProvider="{addrSrv.getAllAddress.lastResult}" width="350" click="currentState='details'">
- <mx:columns>
- <mx:DataGridColumn headerText="Name" width="150" dataField="username"/>
- <mx:DataGridColumn headerText="Phone" dataField="phone"/>
- </mx:columns>
- </mx:DataGrid>
- </mx:HBox>
- <mx:ControlBar id="controlbar1">
- <mx:Button label="New" click="list1.selectedIndex=-1; currentState='details'"/>
- <mx:Button label="Delete" enabled="{list1.selectedIndex >= 0}" click="doDelete()"/>
+ <mx:Form id="form1">
+ <mx:FormItem label="Username:">
+ <mx:TextInput id="login_name" />
+ </mx:FormItem>
+ <mx:FormItem label="Password:">
+ <mx:TextInput id="login_pass"/>
+ </mx:FormItem>
+ <mx:FormItem>
+ <mx:Button label="Login" click="doLogin()" id="button1"/>
+ </mx:FormItem>
+ <mx:ProgressBar width="100%" indeterminate="true" id="progress1" showEffect="Fade" hideEffect="Fade"
+ labelPlacement="center" label="Verifying..." color="#ffffff" visible="false"/>
+ </mx:Form>
+ <mx:ControlBar id="controlbar1" height="10">
+ <mx:Button label="New" click="list1.selectedIndex=-1; currentState='details'" visible="false" id="button2"/>
+ <mx:Button label="Delete" enabled="{list1.selectedIndex >= 0}" click="doDelete()" visible="false" id="button3"/>
</mx:ControlBar>
</mx:Panel>
diff --git a/framework/3rdParty/WsdlGen/Wsdl.php b/framework/3rdParty/WsdlGen/Wsdl.php
index 56676a26..eb41049f 100644
--- a/framework/3rdParty/WsdlGen/Wsdl.php
+++ b/framework/3rdParty/WsdlGen/Wsdl.php
@@ -85,7 +85,7 @@ class Wsdl
{
$this->serviceName = $name;
if ($serviceUri == '') $serviceUri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
- $this->serviceUri = $serviceUri;
+ $this->serviceUri = str_replace('&amp;', '&', $serviceUri);
$this->types = new ArrayObject();
$this->targetNamespace = 'urn:'.$name.'wsdl';
}
diff --git a/framework/Web/Services/TSoapService.php b/framework/Web/Services/TSoapService.php
index e4a1c67e..d838217e 100644
--- a/framework/Web/Services/TSoapService.php
+++ b/framework/Web/Services/TSoapService.php
@@ -286,7 +286,11 @@ class TSoapServer extends TApplicationComponent
private $_uri='';
private $_classMap;
private $_persistent=false;
- private $_wsdlUri='';
+ private $_wsdlUri='';
+
+ private $_requestedMethod;
+
+ private $_server;
/**
* @return string the ID of the SOAP server
@@ -316,31 +320,81 @@ class TSoapServer extends TApplicationComponent
{
Prado::using($provider);
$providerClass=($pos=strrpos($provider,'.'))!==false?substr($provider,$pos+1):$provider;
+ $this->guessMethodCallRequested($providerClass);
$server=$this->createServer();
- $server->setClass($providerClass);
+ $server->setClass($providerClass, $this);
if($this->_persistent)
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
}
else
$server=$this->createServer();
try
- {
+ {
$server->handle();
}
catch (Exception $e)
- {
- $server->fault("SERVER", $e->getMessage(),"", $e->__toString(), '');
+ {
+ if($this->getApplication()->getMode()===TApplicationMode::Debug)
+ $this->fault($e->getMessage(), $e->__toString());
+ else
+ $this->fault($e->getMessage());
}
- }
-
- /**
- * Creates the SoapServer instance.
+ }
+
+ /**
+ * Generate a SOAP fault message.
+ * @param string message title
+ * @param mixed message details
+ * @param string message code, defalt is 'SERVER'.
+ * @param string actors
+ * @param string message name
+ */
+ public function fault($title, $details='', $code='SERVER', $actor='', $name='')
+ {
+ $this->_server->fault($code, $title, $actor, $details, $name);
+ }
+
+ /**
+ * Guess the SOAP method request from the actual SOAP message
+ *
+ * @param string $class current handler class.
+ */
+ protected function guessMethodCallRequested($class)
+ {
+ $namespace = $class.'wsdl';
+ $message = file_get_contents("php://input");
+ $matches= array();
+ if(preg_match('/xmlns:([^=]+)="urn:'.$namespace.'"/', $message, $matches))
+ {
+ if(preg_match('/<'.$matches[1].':([a-zA-Z_]+[a-zA-Z0-9_]+)/', $message, $method))
+ {
+ $this->_requestedMethod = $method[1];
+ }
+ }
+ }
+
+ /**
+ * Soap method guessed from the SOAP message received.
+ * @return string soap method request, null if not found.
+ */
+ public function getRequestedMethod()
+ {
+ return $this->_requestedMethod;
+ }
+
+ /**
+ * Creates the SoapServer instance.
+ * @return SoapServer
*/
protected function createServer()
- {
- if($this->getApplication()->getMode()===TApplicationMode::Debug)
- ini_set("soap.wsdl_cache_enabled",0);
- return new SoapServer($this->getWsdlUri(),$this->getOptions());
+ {
+ if($this->_server===null)
+ {
+ if($this->getApplication()->getMode()===TApplicationMode::Debug)
+ ini_set("soap.wsdl_cache_enabled",0);
+ $this->_server = new SoapServer($this->getWsdlUri(),$this->getOptions());
+ }
+ return $this->_server;
}
/**
@@ -533,7 +587,7 @@ class TSoapServer extends TApplicationComponent
/**
* @return string comma delimit list of class names
- */
+ */
public function setClassMaps($classes)
{
$this->_classMap = $classes;