You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by an...@apache.org on 2015/10/30 10:34:01 UTC
[1/4] syncope git commit: SYNCOPE-701 first working implementation
Repository: syncope
Updated Branches:
refs/heads/master 764fa2eca -> 714557e64
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html b/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
new file mode 100644
index 0000000..9361cdf
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/editUser.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div ng-cloak class="container">
+ <div class="login-container" ng-controller="UserController" ng-init="initUser();" style="box-sizing: border-box; ">
+
+ <div id="form-container" class="col-md-6 col-md-offset-3">
+
+
+ <div>
+ <div class="page-header" style="text-align: left; font-weight: 700;">
+ <span ng-show="createMode">New User</span>
+ <span ng-show="!createMode">User {{user.username}}</span>
+ </div>
+ <div class="breadcrumb-header text-center">
+
+ <!-- the links to our nested states using relative paths -->
+ <!-- add the active class if the state matches our ui-sref -->
+ <!--<div id="status-buttons" class="text-center">-->
+ <div class="row">
+ <div growl reference="2" inline="true"></div>
+ <div id="status-buttons" class="btn-group btn-breadcrumb">
+ <a href="#/self" class="btn btn-default"><i class="glyphicon glyphicon-home"></i></a>
+ <!--add class breadcrumb-disabled-link to buttons to prevent click-->
+ <a ui-sref-active="active" ui-sref=".credentials" class="btn btn-default">Credentials</a>
+ <a ui-sref-active="active" ui-sref=".plainSchemas" class="btn btn-default">Plain Schemas</a>
+ <a ui-sref-active="active" ui-sref=".derivedSchemas" class="btn btn-default">Derived Schemas</a>
+ <a ui-sref-active="active" ui-sref=".virtualSchemas" class="btn btn-default">Virtual Schemas</a>
+ <a ui-sref-active="active" ui-sref=".groups" class="btn btn-default">Groups</a>
+ <a ui-sref-active="active" ui-sref=".resources" class="btn btn-default">Resources</a>
+ </div>
+ </div>
+ </div>
+ <form class="signup-form" name="userForm" ng-submit="saveUser(user)" novalidate>
+
+ <div id="form-views" ui-view>
+
+ <!-- <div class="form-group row">
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="next" ui-sref="create.credentials" class="btn btn-block btn-signin">
+ Start <span class="glyphicon glyphicon-circle-arrow-right"></span>
+ </a>
+ <a id="cancel" href="#/self" class="btn btn-link">Cancel</a>
+ </div>
+ </div>-->
+
+ </div>
+ <!-- <div class="form-actions">
+ <button type="submit" ng-disabled="form.$invalid || vm.dataLoading" class="btn btn-primary" ng-click="saveUser()">Register</button>
+ <img ng-if="vm.dataLoading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
+ <a href="#/self" class="btn btn-link">Cancel</a>
+ </div>-->
+ </form>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/generic-error.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/generic-error.html b/client/enduser/src/main/resources/META-INF/resources/app/views/generic-error.html
new file mode 100644
index 0000000..2ca6c58
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/generic-error.html
@@ -0,0 +1,24 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <body>
+ <div>PAGE NOT FOUND</div>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/home.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/home.html b/client/enduser/src/main/resources/META-INF/resources/app/views/home.html
new file mode 100644
index 0000000..ca365ff
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/home.html
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+ <body>
+ <div>TITLE GET FROM CONTROLLER:</div>
+ <p>{{title}}</p>
+ <p>{{subtitle}}</p>
+ <p>{{name}}</p>
+
+ <button type="button" ng-click="">Password Reset</button>
+ <button type="button" ng-click="">Self Registration</button>
+ <button type="button" ng-click="">Self Update</button>
+ <button type="button" ng-click="sampleAPI()">Sample</button>
+ <button type="button" ng-click="errorAPI()">Error</button>
+
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html b/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
new file mode 100644
index 0000000..793334d
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/navigationButtons.html
@@ -0,0 +1,8 @@
+<div class="col-xs-6 col-xs-offset-3">
+ <a ng-show="next !== 'none'" id="next" ui-sref="{{next}}" class="btn btn-default">
+ Next <span class="glyphicon glyphicon-circle-arrow-right"></span>
+ </a>
+ <a ng-show="previous !== 'none'" id="previous" ui-sref="{{previous}}" class="btn btn-default">
+ <span class="glyphicon glyphicon-circle-arrow-left"></span> Previous
+ </a>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/self.html b/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
new file mode 100644
index 0000000..0139697
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/self.html
@@ -0,0 +1,131 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+ <meta charset="UTF-8"/>
+ <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'/>
+
+ <title>Apache Syncope Enduser - Login</title>
+ </head>
+
+ <body>
+
+ <div ng-cloak class="container">
+
+ <div id="login-container" ng-controller="LoginController" style="box-sizing: border-box; ">
+
+ <!-- <div id="logo">
+ <a href="/">
+ <img class="login-logo" src="img/logo-green.png" />
+ </a>
+ </div>-->
+ <div id="login">
+ <div class="logout">
+ <a href="javascript:void(0);" class="btn btn-danger btn-signin" ng-click="logout()" ng-show="isLogged()" title="Logout">
+ <i class="glyphicon glyphicon-off"></i>
+ </a>
+ </div>
+ <div>
+ <div id="language" class="form-group" ng-controller="LanguageController" ng-init="init()">
+ <div id="languageContainer" class="col-xs-2">
+
+ <select class="form-control" ng-options="language.name for language in languages.availableLanguages track by language.id"
+ ng-model="languages.selectedLanguage" ></select>
+
+ </div>
+ </div>
+
+ <h3>Welcome to Apache Syncope Enduser</h3>
+ <h5 ng-show="!isLogged()">please login to self update</h5>
+
+ <div id="login-form" class="form">
+ <div growl reference="1" inline="true"></div>
+ </div>
+
+ <form id="login-form" class="form" novalidate ng-show="!isLogged()" >
+
+ <div class="form-group">
+ <input autofocus="autofocus" type="text" class="form-control" id="login-username" placeholder="Username"
+ ng-required ng-model="credentials.username" placeholder="username">
+ </div>
+
+ <div class="form-group">
+ <input type="password" class="form-control" id="login-password" placeholder="Password"
+ ng-required ng-model="credentials.password" placeholder="password">
+ </div>
+
+ <div class="form-group">
+
+ <button type="submit" id="login-btn" class="btn btn-default btn-signin login-btn" ng-click="login(credentials)">Login</button>
+ <a href="javascript:void(0);" class="btn btn-link" ng-click="selfCreate()">Self Registration</a>
+ <a href="javascript:void(0);" class="btn btn-link" ng-click="passwordReset()">Password Reset</a>
+ </div>
+ </form>
+
+ </div>
+
+ </div>
+
+ </div>
+
+ </div> <!-- /#login -->
+
+ <!-- <div id="initialLoaderDiv">
+ <img src="img/busy.gif" class="ajax-loader"/>
+ </div>-->
+ </div> <!-- /#login-container -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <!-- <div class="container" ng-cloak ng-controller="LoginController">
+ <div class="card card-container">
+ <img class="login-logo" src="img/logo-green.png" />
+
+ <div growl></div>
+
+ <form class="form-signin" novalidate ng-show="!isLogged()">
+ <input type="text" id="username" class="form-control" ng-required autofocus="autofocus" ng-model="credentials.username" />
+ <input type="password" id="password" class="form-control" required="required" ng-model="credentials.password" />
+
+ <select id="language" style="width: 100%"
+ ng-options="language.name for language in languages.availableLanguages track by language.id"
+ ng-model="languages.selectedLanguage"></select>
+
+ <button type="submit" class="btn btn-lg btn-primary btn-block btn-signin" ng-click="login(credentials)">Login</button>
+ </form>
+
+
+
+ </div>
+ </div>-->
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
new file mode 100644
index 0000000..cfd1ba6
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-credentials.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<div id="attribute" class="form-group">
+ <label for="user.username">Username</label>
+ <input name="username" type="text" class="form-control" ng-model="user.username" required placeholder="username" >
+ <p ng-show="(userForm.username.$error.required && !userForm.username.$pristine)" class="text-validation-error">Username is required</p>
+</div>
+
+<div id="attribute" class="form-group">
+ <label for="user.password">Password</label>
+ <input type="password" class="form-control" name="password" ng-model="user.password" equals="{{confirmPassword.value}}"
+ placeholder="password">
+</div>
+
+<div id="attribute" class="form-group">
+ <label for="confirmPassword">Confirm Password</label>
+ <input name="confirmPassword" type="password" class="form-control" equals="{{user.password}}" ng-model="confirmPassword.value"
+ placeholder="confirm password">
+ <p ng-show="userForm.confirmPassword.$error.equals" class="text-validation-error">Password and confirm password must be equal</p>
+</div>
+
+<div id="attribute" class="form-group">
+ <label for="securityQuestion">Security Question</label>
+ <select name="securityQuestion" class="form-control"
+ ng-model="user.securityQuestion"
+ ng-options="securityQuestion.key as securityQuestion.content for securityQuestion in availableSecurityQuestions">
+ <option value="">Select security question</option>
+ </select>
+</div>
+
+<div id="attribute" class="form-group">
+ <label for="securityAnswer">Security Answer</label>
+ <input ng-disabled="user.securityQuestion === initialSecurityQuestion" name="securityAnswer" type="text" class="form-control" ng-model="user.securityAnswer"
+ placeholder="security answer">
+</div>
+
+<div class="form-group row">
+ <navigation-buttons ng-show="createMode" next="create.plainSchemas" previous="none"></navigation-buttons>
+ <navigation-buttons ng-show="!createMode" next="update.plainSchemas" previous="none"></navigation-buttons>
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="cancel" href="#/self" class="btn btn-danger">Cancel</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
new file mode 100644
index 0000000..a92b9c2
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-derived-schemas.html
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div id="attribute-derived" class="form-group" >
+ <div>
+ <dynamic-derived-attributes user="user" form="dynamicForm"></dynamic-derived-attributes>
+ </div>
+ <!-- <div style="color:#dd301b" ng-if="attribute.validated == false" class="row-fluid">
+ <div class="col-md-5"></div>
+ <div class="col-md-7">{{attribute.validationMessage| translate }}</div>
+ </div>-->
+ <!--</div>-->
+</div>
+
+<div class="form-group row">
+ <navigation-buttons ng-show="createMode" next="create.virtualSchemas" previous="create.plainSchemas"></navigation-buttons>
+ <navigation-buttons ng-show="!createMode" next="update.virtualSchemas" previous="update.plainSchemas"></navigation-buttons>
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="cancel" href="#/self" class="btn btn-danger">Cancel</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
new file mode 100644
index 0000000..58475bb
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div class="form-group row upper-select">
+ <label>Realm</label>
+ <select class="form-control"
+ ng-disabled="true"
+ ng-model="user.realm"
+ ng-required="true">
+ <option ng-repeat="realm in availableRealms" value="{{realm}}">{{realm}}</option>
+ </select>
+</div>
+
+<div class="form-group row">
+ <navigation-buttons ng-show="createMode" next="create.resources" previous="create.virtualSchemas"></navigation-buttons>
+ <navigation-buttons ng-show="!createMode" next="update.resources" previous="update.virtualSchemas"></navigation-buttons>
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="cancel" href="#/self" class="btn btn-danger">Cancel</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
new file mode 100644
index 0000000..2639197
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-plain-schemas.html
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div>
+ <dynamic-plain-attributes form="dynamicForm" user="user"></dynamic-plain-attributes>
+</div>
+
+<!-- <div style="color:#dd301b" ng-if="attribute.validated == false" class="row-fluid">
+ <div class="col-md-5"></div>
+ <div class="col-md-7">{{attribute.validationMessage| translate }}</div>
+ </div>-->
+<!--</div>-->
+<!--</div>-->
+
+<div class="form-group row">
+ <navigation-buttons ng-show="createMode" next="create.derivedSchemas" previous="create.credentials"></navigation-buttons>
+ <navigation-buttons ng-show="!createMode" next="update.derivedSchemas" previous="update.credentials"></navigation-buttons>
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="cancel" href="#/self" class="btn btn-danger">Cancel</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
new file mode 100644
index 0000000..91a99f6
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-resources.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div class="form-group row">
+ <navigation-buttons ng-show="createMode" next="none" previous="create.groups"></navigation-buttons>
+ <navigation-buttons ng-show="!createMode" next="none" previous="update.groups"></navigation-buttons>
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="cancel" href="#/self" class="btn btn-danger">Cancel</a>
+ <button id="save" type="submit" class="btn btn-success">Save</button>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
new file mode 100644
index 0000000..1d77c80
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-virtual-schemas.html
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<div id="attribute-virtual" class="form-group">
+ <div>
+ <dynamic-virtual-attributes form="dynamicForm" user="user"></dynamic-virtual-attributes>
+ </div>
+ <!-- <div style="color:#dd301b" ng-if="attribute.validated == false" class="row-fluid">
+ <div class="col-md-5"></div>
+ <div class="col-md-7">{{attribute.validationMessage| translate }}</div>
+ </div>-->
+ <!--</div>-->
+</div>
+
+<div class="form-group row">
+ <navigation-buttons ng-show="createMode" next="create.groups" previous="create.derivedSchemas"></navigation-buttons>
+ <navigation-buttons ng-show="!createMode" next="update.groups" previous="update.derivedSchemas"></navigation-buttons>
+ <div class="col-xs-6 col-xs-offset-3">
+ <a id="cancel" href="#/self" class="btn btn-danger">Cancel</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/web-fragment.xml
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/web-fragment.xml b/client/enduser/src/main/resources/META-INF/web-fragment.xml
new file mode 100644
index 0000000..b949d4c
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/web-fragment.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
+ id="${pom.artifactId}" version="3.1">
+
+ <!--causes problem if deployed with other fragments-->
+ <display-name>Apache Syncope ${syncope.version} Enduser</display-name>
+
+<!-- <context-param>
+ <param-name>configuration</param-name>
+ <param-value>deployment</param-value>
+ </context-param>
+
+ <filter>
+ <filter-name>SyncopeEnduser</filter-name>
+ <filter-class>org.apache.wicket.protocol.ws.javax.JavaxWebSocketFilter</filter-class>
+ <init-param>
+ <param-name>filterMappingUrlPattern</param-name>
+ <param-value>/*</param-value>
+ </init-param>
+ <init-param>
+ <param-name>applicationClassName</param-name>
+ <param-value>org.apache.syncope.client.enduser.SyncopeEnduserApplication</param-value>
+ </init-param>
+ </filter>-->
+
+ <filter>
+ <filter-name>SyncopeEnduser</filter-name>
+ <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+ <init-param>
+ <param-name>applicationClassName</param-name>
+ <param-value>org.apache.syncope.client.enduser.SyncopeEnduserApplication</param-value>
+ </init-param>
+ <init-param>
+ <param-name>filterMappingUrlPattern</param-name>
+ <param-value>/*</param-value>
+ </init-param>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>SyncopeEnduser</filter-name>
+ <url-pattern>/*</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>INCLUDE</dispatcher>
+ </filter-mapping>
+
+ <!--SESSION TIMEOUT (MINUTES)-->
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+
+</web-fragment>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/enduser.properties
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/enduser.properties b/client/enduser/src/main/resources/enduser.properties
new file mode 100644
index 0000000..4dd1cbe
--- /dev/null
+++ b/client/enduser/src/main/resources/enduser.properties
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+enduser.directory=${conf.directory}
+scheme=http
+host=localhost
+port=8080
+rootPath=/syncope/rest/
+
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
+
+storePassword=true
+
+version=${syncope.version}
+license=${licenseUrl}
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/HomePage.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/HomePage.html b/client/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/HomePage.html
new file mode 100644
index 0000000..55d71a4
--- /dev/null
+++ b/client/enduser/src/main/resources/org/apache/syncope/client/enduser/pages/HomePage.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html>
+
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/test/java/org/apache/syncope/client/enduser/SyncopeEnduserApplicationTest.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/test/java/org/apache/syncope/client/enduser/SyncopeEnduserApplicationTest.java b/client/enduser/src/test/java/org/apache/syncope/client/enduser/SyncopeEnduserApplicationTest.java
new file mode 100644
index 0000000..4a77739
--- /dev/null
+++ b/client/enduser/src/test/java/org/apache/syncope/client/enduser/SyncopeEnduserApplicationTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser;
+
+import org.apache.syncope.client.enduser.pages.HomePage;
+import org.apache.wicket.Session;
+import org.apache.wicket.protocol.http.WebSession;
+import org.apache.wicket.protocol.http.mock.MockHttpServletResponse;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.util.tester.WicketTester;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SyncopeEnduserApplicationTest {
+
+ private WicketTester tester;
+
+ static class SyncopeEnduserMockSession extends WebSession {
+
+ private static final long serialVersionUID = -2500230416352618497L;
+
+ SyncopeEnduserMockSession(Request request) {
+ super(request);
+ }
+ }
+
+ @Before
+ public void setUp() {
+ tester = new WicketTester(new SyncopeEnduserApplication() {
+
+ private static final long serialVersionUID = 1445165406200746511L;
+
+ @Override
+ public Session newSession(Request request, Response response) {
+ return new SyncopeEnduserMockSession(request);
+ }
+
+ });
+ }
+
+ @Test
+ public void testRedirectToIndex() {
+ tester.setFollowRedirects(false);
+ tester.startPage(HomePage.class);
+ tester.assertNoErrorMessage();
+ MockHttpServletResponse response = tester.getLastResponse();
+ Assert.assertThat(response.getRedirectLocation(), CoreMatchers.equalTo("app/"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 68bd1e5..0cefabb 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -60,6 +60,7 @@ under the License.
<module>lib</module>
<module>console</module>
<module>cli</module>
+ <module>enduser</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
index 6587d1d..f0c2d15 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/Entitlement.java
@@ -46,22 +46,14 @@ public final class Entitlement {
public static final String REALM_DELETE = "REALM_DELETE";
- public static final String ANYTYPECLASS_LIST = "ANYTYPECLASS_LIST";
-
public static final String ANYTYPECLASS_CREATE = "ANYTYPECLASS_CREATE";
- public static final String ANYTYPECLASS_READ = "ANYTYPECLASS_READ";
-
public static final String ANYTYPECLASS_UPDATE = "ANYTYPECLASS_UPDATE";
public static final String ANYTYPECLASS_DELETE = "ANYTYPECLASS_DELETE";
- public static final String ANYTYPE_LIST = "ANYTYPE_LIST";
-
public static final String ANYTYPE_CREATE = "ANYTYPE_CREATE";
- public static final String ANYTYPE_READ = "ANYTYPE_READ";
-
public static final String ANYTYPE_UPDATE = "ANYTYPE_UPDATE";
public static final String ANYTYPE_DELETE = "ANYTYPE_DELETE";
@@ -90,8 +82,6 @@ public final class Entitlement {
public static final String SCHEMA_CREATE = "SCHEMA_CREATE";
- public static final String SCHEMA_READ = "SCHEMA_READ";
-
public static final String SCHEMA_UPDATE = "SCHEMA_UPDATE";
public static final String SCHEMA_DELETE = "SCHEMA_DELETE";
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
index 1743370..7ccd2bf 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
@@ -44,7 +44,7 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
@Autowired
private AnyTypeClassDAO anyTypeClassDAO;
- @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_READ + "')")
+ @PreAuthorize("isAuthenticated()")
public AnyTypeClassTO read(final String key) {
AnyTypeClass anyType = anyTypeClassDAO.find(key);
if (anyType == null) {
@@ -56,7 +56,7 @@ public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO
return binder.getAnyTypeClassTO(anyType);
}
- @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_LIST + "')")
+ @PreAuthorize("isAuthenticated()")
public List<AnyTypeClassTO> list() {
return CollectionUtils.collect(anyTypeClassDAO.findAll(), new Transformer<AnyTypeClass, AnyTypeClassTO>() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 1ff60c7..6bd0fd5 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -46,7 +46,7 @@ public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
@Autowired
private AnyTypeDAO anyTypeDAO;
- @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_READ + "')")
+ @PreAuthorize("isAuthenticated()")
public AnyTypeTO read(final String key) {
AnyType anyType = anyTypeDAO.find(key);
if (anyType == null) {
@@ -58,7 +58,7 @@ public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
return binder.getAnyTypeTO(anyType);
}
- @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_LIST + "')")
+ @PreAuthorize("isAuthenticated()")
public List<AnyTypeTO> list() {
return CollectionUtils.collect(anyTypeDAO.findAll(), new Transformer<AnyType, AnyTypeTO>() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
index 3da4a76..cbd5f64 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SchemaLogic.java
@@ -180,7 +180,7 @@ public class SchemaLogic extends AbstractTransactionalLogic<AbstractSchemaTO> {
return result;
}
- @PreAuthorize("hasRole('" + Entitlement.SCHEMA_READ + "')")
+ @PreAuthorize("isAuthenticated()")
@SuppressWarnings("unchecked")
public <T extends AbstractSchemaTO> T read(final SchemaType schemaType, final String schemaName) {
T read;
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index e5cf78b..811b429 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -118,15 +118,6 @@ public class AuthenticationITCase extends AbstractITCase {
@Test
public void testUserSchemaAuthorization() {
- // 0. create a role that can only read schemas
- RoleTO roleTO = new RoleTO();
- roleTO.setName("authRole" + getUUIDString());
- roleTO.getEntitlements().add(Entitlement.SCHEMA_READ);
- roleTO.getRealms().add("/odd");
-
- roleTO = createRole(roleTO);
- assertNotNull(roleTO);
-
String schemaName = "authTestSchema" + getUUIDString();
// 1. create a schema (as admin)
@@ -140,8 +131,6 @@ public class AuthenticationITCase extends AbstractITCase {
// 2. create an user with the role created above (as admin)
UserTO userTO = UserITCase.getUniqueSampleTO("auth@test.org");
- userTO.getRoles().add(roleTO.getKey());
-
userTO = createUser(userTO).getAny();
assertNotNull(userTO);
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
new file mode 100644
index 0000000..aee8f79
--- /dev/null
+++ b/fit/enduser-reference/pom.xml
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-fit</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope FIT Enduser Reference</name>
+ <description>Apache Syncope FIT Enduser Reference</description>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-enduser-reference</artifactId>
+ <packaging>war</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-enduser</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>javax.servlet.jsp-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency><!--
+-->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency><!--
+-->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency><!--
+-->
+ <dependency>
+ <groupId>com.lmax</groupId>
+ <artifactId>disruptor</artifactId>
+ </dependency><!--
+-->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <scope>provided</scope>
+ </dependency><!--
+-->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-build-tools</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.tirasa.connid.bundles.soap</groupId>
+ <artifactId>wssample</artifactId>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <scope>test</scope>
+ </dependency><!--
+
+ SELENIUM INTEGRATION TEST
+ <dependency>
+ <groupId>org.seleniumhq.selenium</groupId>
+ <artifactId>selenium-java</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.seleniumhq.selenium</groupId>
+ <artifactId>selenium-api</artifactId>
+ <scope>test</scope>
+ </dependency>-->
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <container>
+ <dependencies>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ </dependencies>
+ </container>
+ <configuration>
+ <type>standalone</type>
+ <properties>
+ <cargo.servlet.port>${cargo.servlet.port}</cargo.servlet.port>
+ <cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port>
+ <cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port>
+
+ <cargo.jvmargs>-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m</cargo.jvmargs>
+ </properties>
+ <configfiles>
+ <configfile>
+ <file>${project.build.directory}/classes/context.xml</file>
+ <todir>conf/</todir>
+ <tofile>context.xml</tofile>
+ </configfile>
+ </configfiles>
+ </configuration>
+ <deployables>
+ <deployable>
+ <groupId>net.tirasa.connid.bundles.soap</groupId>
+ <artifactId>wssample</artifactId>
+ <type>war</type>
+ <properties>
+ <context>wssample</context>
+ </properties>
+ </deployable>
+ <deployable>
+ <groupId>org.apache.syncope.fit</groupId>
+ <artifactId>syncope-fit-build-tools</artifactId>
+ <type>war</type>
+ <properties>
+ <context>syncope-fit-build-tools</context>
+ </properties>
+ </deployable>
+ <deployable>
+ <location>${basedir}/../core-reference/target/syncope-fit-core-reference-${project.version}</location>
+ <pingURL>http://localhost:${cargo.servlet.port}/syncope/cacheStats.jsp</pingURL>
+ <pingTimeout>60000</pingTimeout>
+ <properties>
+ <context>syncope</context>
+ </properties>
+ </deployable>
+ <deployable>
+ <location>${project.build.directory}/${project.build.finalName}</location>
+ <properties>
+ <context>syncope-enduser</context>
+ </properties>
+ </deployable>
+ </deployables>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <resourceIncludes>src/main/resources/**/*.properties</resourceIncludes>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>ianal-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>debug</id>
+
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+
+ <build>
+ <defaultGoal>clean verify cargo:run</defaultGoal>
+
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <configuration>
+ <properties>
+ <cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
+ -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m</cargo.jvmargs>
+ </properties>
+ </configuration>
+ </configuration>
+ <executions>
+ <execution>
+ <id>start-container</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>stop-container</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>skipTests</id>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <deployables>
+ <deployable>
+ <location>${project.build.directory}/${project.build.finalName}.war</location>
+ </deployable>
+ </deployables>
+ </configuration>
+ <executions>
+ <execution>
+ <id>install-container</id>
+ <phase>package</phase>
+ <goals>
+ <goal>install</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>start-container</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>stop-container</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>jrebel</id>
+
+ <properties>
+ <javaagent>-javaagent:${env.REBEL_HOME}/jrebel.jar</javaagent>
+ </properties>
+
+ <build>
+ <defaultGoal>clean verify cargo:run</defaultGoal>
+
+ <plugins>
+ <plugin>
+ <groupId>org.zeroturnaround</groupId>
+ <artifactId>jrebel-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <classpath>
+ <fallback>default</fallback>
+ <resources>
+ <resource/>
+ <resource>
+ <directory>${basedir}/../../client/enduser/target/classes</directory>
+ </resource>
+ </resources>
+ </classpath>
+
+ <web>
+ <resources>
+ <resource/>
+ <resource>
+ <target>/</target>
+ <directory>${basedir}/../../client/enduser/target/classes/META-INF/resources/</directory>
+ </resource>
+ </resources>
+ </web>
+
+ <alwaysGenerate>true</alwaysGenerate>
+ </configuration>
+ <executions>
+ <execution>
+ <id>generate-rebel-xml</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <configuration>
+ <properties>
+ <cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
+ -noverify ${javaagent} -Drebel.spring_plugin=true
+ -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m</cargo.jvmargs>
+ </properties>
+ </configuration>
+ </configuration>
+ <executions>
+ <execution>
+ <id>start-container</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>stop-container</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>apache-release</id>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/src/main/resources/context.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/src/main/resources/context.xml b/fit/enduser-reference/src/main/resources/context.xml
new file mode 100644
index 0000000..471d561
--- /dev/null
+++ b/fit/enduser-reference/src/main/resources/context.xml
@@ -0,0 +1,23 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<Context>
+ <!-- Disable session persistence across Tomcat restarts -->
+ <Manager pathname=""/>
+</Context>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/src/main/resources/enduser.properties
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/src/main/resources/enduser.properties b/fit/enduser-reference/src/main/resources/enduser.properties
new file mode 100644
index 0000000..96b0dea
--- /dev/null
+++ b/fit/enduser-reference/src/main/resources/enduser.properties
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+enduser.directory=${conf.directory}
+scheme=http
+host=localhost
+port=9080
+rootPath=/syncope/rest/
+
+anonymousUser=${anonymousUser}
+anonymousKey=${anonymousKey}
+
+storePassword=true
+
+version=${syncope.version}
+license=${licenseUrl}
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/src/main/resources/log4j2.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/src/main/resources/log4j2.xml b/fit/enduser-reference/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..ced0e34
--- /dev/null
+++ b/fit/enduser-reference/src/main/resources/log4j2.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<configuration status="WARN">
+
+ <appenders>
+
+ <RollingRandomAccessFile name="main" fileName="${log.directory}/enduser.log"
+ filePattern="${log.directory}/enduser-%d{yyyy-MM-dd}.log.gz"
+ immediateFlush="false" append="true">
+ <PatternLayout>
+ <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
+ </PatternLayout>
+ <Policies>
+ <TimeBasedTriggeringPolicy/>
+ <SizeBasedTriggeringPolicy size="250 MB"/>
+ </Policies>
+ </RollingRandomAccessFile>
+
+ </appenders>
+
+ <loggers>
+
+ <asyncLogger name="org.apache.syncope.client.lib" additivity="false" level="OFF">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.apache.syncope.client.enduser" additivity="false" level="DEBUG">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <asyncLogger name="org.apache.wicket" additivity="false" level="DEBUG">
+ <appender-ref ref="main"/>
+ </asyncLogger>
+
+ <root level="DEBUG">
+ <appender-ref ref="main"/>
+ </root>
+
+ </loggers>
+
+</configuration>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml b/fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml
new file mode 100644
index 0000000..6400bc2
--- /dev/null
+++ b/fit/enduser-reference/src/main/webapp/WEB-INF/glassfish-web.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+
+-->
+<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD
+GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
+<glassfish-web-app error-url="">
+ <class-loader delegate="false"/>
+</glassfish-web-app>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/fit/enduser-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..f38ebfc
--- /dev/null
+++ b/fit/enduser-reference/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
+ <deployment>
+ <exclude-subsystems>
+ <subsystem name="webservices"/>
+ <subsystem name="jaxrs"/>
+ </exclude-subsystems>
+ <dependencies>
+ <module name="org.apache.xalan"/>
+ </dependencies>
+ <exclusions>
+ <module name="javax.ws.rs.api"/>
+ <module name="org.apache.cxf"/>
+ <module name="org.apache.cxf.impl"/>
+ <module name="org.slf4j"/>
+ <module name="org.slf4j.impl"/>
+ </exclusions>
+ </deployment>
+</jboss-deployment-structure>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/enduser-reference/src/main/webapp/WEB-INF/weblogic.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/src/main/webapp/WEB-INF/weblogic.xml b/fit/enduser-reference/src/main/webapp/WEB-INF/weblogic.xml
new file mode 100644
index 0000000..6e6bd30
--- /dev/null
+++ b/fit/enduser-reference/src/main/webapp/WEB-INF/weblogic.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
+ http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
+
+ <context-root>syncope-console</context-root>
+
+ <container-descriptor>
+ <prefer-application-packages>
+ <package-name>org.apache.commons.*</package-name>
+ <package-name>org.slf4j.*</package-name>
+ <package-name>com.fasterxml.jackson.*</package-name>
+ </prefer-application-packages>
+ </container-descriptor>
+
+</weblogic-web-app>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/fit/pom.xml
----------------------------------------------------------------------
diff --git a/fit/pom.xml b/fit/pom.xml
index 203e414..072e37a 100644
--- a/fit/pom.xml
+++ b/fit/pom.xml
@@ -60,6 +60,7 @@ under the License.
<module>build-tools</module>
<module>core-reference</module>
<module>console-reference</module>
+ <module>enduser-reference</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bfdfd51..a5ee74a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -388,7 +388,20 @@ under the License.
<wicket.version>7.1.0</wicket.version>
<wicket-jqueryui.version>7.1.0</wicket-jqueryui.version>
-
+
+ <angular.version>1.4.7</angular.version>
+ <angular-route.version>1.4.7</angular-route.version>
+ <angular-resource.version>1.4.7</angular-resource.version>
+ <angular-cookies.version>1.4.7</angular-cookies.version>
+ <angular-animate.version>1.4.7</angular-animate.version>
+ <angular-ui-router.version>0.2.15</angular-ui-router.version>
+ <angular-ui-bootstrap.version>0.14.0</angular-ui-bootstrap.version>
+ <angular-ui-select.version>0.13.1</angular-ui-select.version>
+ <angular-sanitize.version>1.4.7</angular-sanitize.version>
+ <angular-growl-2.version>0.7.3</angular-growl-2.version>
+ <select2.version>3.4.8</select2.version>
+ <FileSaver.version>0.0.2</FileSaver.version>
+
<izpack.version>5.0.5</izpack.version>
<httpclient.version>4.3.6</httpclient.version>
<maven-invoker.version>2.1.1</maven-invoker.version>
@@ -999,6 +1012,79 @@ under the License.
<artifactId>jquery-cookie</artifactId>
<version>${jquery-cookie.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular</artifactId>
+ <version>${angular.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-route</artifactId>
+ <version>${angular-route.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-resource</artifactId>
+ <version>${angular-resource.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-cookies</artifactId>
+ <version>${angular-cookies.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-ui-router</artifactId>
+ <version>${angular-ui-router.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-animate</artifactId>
+ <version>${angular-animate.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-ui-bootstrap</artifactId>
+ <version>${angular-ui-bootstrap.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-ui-select</artifactId>
+ <version>${angular-ui-select.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-sanitize</artifactId>
+ <version>${angular-sanitize.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-growl-2</artifactId>
+ <version>${angular-growl-2.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>select2</artifactId>
+ <version>${select2.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>jquery</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>FileSaver.js</artifactId>
+ <version>${FileSaver.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.beust</groupId>
+ <artifactId>jcommander</artifactId>
+ <version>1.47</version>
+ </dependency>
<dependency>
<groupId>org.codehaus.izpack</groupId>
@@ -1376,6 +1462,7 @@ under the License.
<exclude>**/META-INF/cxf/**</exclude>
<exclude>**/META-INF/services/**</exclude>
<exclude>**/META-INF/MANIFEST.MF</exclude>
+ <exclude>**/META-INF/resources/app/views/**</exclude>
<exclude>**/*.csv</exclude>
<exclude>**/archetype-resources/**</exclude>
<exclude>**/AdminLTE*/**</exclude>
[2/4] syncope git commit: SYNCOPE-701 first working implementation
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif b/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif
new file mode 100644
index 0000000..766cf24
Binary files /dev/null and b/client/enduser/src/main/resources/META-INF/resources/app/img/ajax-loader.gif differ
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif b/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif
new file mode 100644
index 0000000..e77264f
Binary files /dev/null and b/client/enduser/src/main/resources/META-INF/resources/app/img/busy.gif differ
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png b/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png
new file mode 100644
index 0000000..aa2f3e2
Binary files /dev/null and b/client/enduser/src/main/resources/META-INF/resources/app/img/favicon.png differ
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png b/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png
new file mode 100644
index 0000000..c57b86c
Binary files /dev/null and b/client/enduser/src/main/resources/META-INF/resources/app/img/logo-green.png differ
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png b/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png
new file mode 100644
index 0000000..f05105e
Binary files /dev/null and b/client/enduser/src/main/resources/META-INF/resources/app/img/logo.png differ
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/index.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/index.html b/client/enduser/src/main/resources/META-INF/resources/app/index.html
new file mode 100644
index 0000000..6cb7ae6
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/index.html
@@ -0,0 +1,116 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!DOCTYPE html>
+<!--[if lt IE 7]> <html lang="en" ng-app="myApp" class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
+<!--[if IE 7]> <html lang="en" ng-app="myApp" class="no-js lt-ie9 lt-ie8"> <![endif]-->
+<!--[if IE 8]> <html lang="en" ng-app="myApp" class="no-js lt-ie9"> <![endif]-->
+<!--[if gt IE 8]><!--> <html lang="en" ng-app="SyncopeEnduserApp" class="no-js"> <!--<![endif]-->
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <title>SyncopeEnduserApp</title>
+ <meta name="description" content="">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <!--<link rel="stylesheet" href="bower_components/html5-boilerplate/dist/css/normalize.css">-->
+ <!--<link rel="stylesheet" href="bower_components/html5-boilerplate/dist/css/main.css">-->
+ <link rel="stylesheet" href="css/app.css">
+ <!--<script src="bower_components/html5-boilerplate/dist/js/vendor/modernizr-2.8.3.min.js"></script>-->
+ </head>
+ <body ng-cloak >
+ <!--<button ng-click=""-->
+
+ <!--[if lt IE 7]>
+ <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
+ <![endif]-->
+
+ <!--<div ng-view ng-cloak ng-controller="ApplicationController"></div>-->
+ <div ui-view ng-cloak ng-controller="ApplicationController"></div>
+
+ <!-- <footer id="footer" class="hidden-print">
+ <ul class="nav pull-right">
+ <li>
+ Copyright © 2015, Apache Syncope
+ </li>
+ </ul>
+ </footer>-->
+
+ <!--default global growl message-->
+ <!--<div growl></div>-->
+
+ <!-- <div class="hidden-print" id="initialLoaderDiv">
+ <img src="img/ajax-loader.gif" class="ajax-loader"/>
+ </div>-->
+
+ <!-- In production use:
+ <script src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>
+ -->
+ <script type="text/javascript" src="../webjars/jquery/${jquery.version}/jquery.js"></script>
+ <script src="../webjars/angular/${angular.version}/angular.js"></script>
+ <script src="../webjars/angular-ui-router/${angular-ui-router.version}/angular-ui-router.js"></script>
+ <script src="../webjars/angular-animate/${angular-animate.version}/angular-animate.js"></script>
+ <script src="../webjars/angular-resource/${angular-resource.version}/angular-resource.js"></script>
+ <script src="../webjars/angular-cookies/${angular-cookies.version}/angular-cookies.js"></script>
+ <script src="../webjars/angular-sanitize/${angular-sanitize.version}/angular-sanitize.js"></script>
+ <script src="../webjars/angular-ui-bootstrap/${angular-ui-bootstrap.version}/ui-bootstrap-tpls.js"></script>
+ <script src="../webjars/angular-ui-select/${angular-ui-select.version}/select.js"></script>
+ <script src="../webjars/angular-growl-2/${angular-growl-2.version}/angular-growl.js"></script>
+ <script type="text/javascript" src="../webjars/bootstrap-select/${bootstrap-select.version}/js/bootstrap-select.min.js"></script>
+ <script src="../webjars/FileSaver.js/${FileSaver.version}/FileSaver.js" type="text/javascript"></script>
+ <!--main angular application-->
+ <script src="js/app.js"></script>
+ <!--services-->
+ <script src="js/services/authService.js"></script>
+ <script src="js/services/userSelfService.js"></script>
+ <script src="js/services/schemaService.js"></script>
+ <script src="js/services/realmService.js"></script>
+ <script src="js/services/securityQuestionService.js"></script>
+ <!--controllers-->
+ <script src="js/controllers/HomeController.js"></script>
+ <script src="js/controllers/LoginController.js"></script>
+ <script src="js/controllers/LanguageController.js"></script>
+ <script src="js/controllers/UserController.js"></script>
+ <!--directives-->
+ <script src="js/directives/dynamicAttribute.js"></script>
+ <script src="js/directives/dynamicPlainAttributes.js"></script>
+ <script src="js/directives/dynamicDerivedAttributes.js"></script>
+ <script src="js/directives/dynamicVirtualAttributes.js"></script>
+ <script src="js/directives/navigationButtons.js"></script>
+ <script src="js/directives/loader.js"></script>
+ <script src="js/directives/equals.js"></script>
+ <!--filters-->
+ <script src="js/filters/propsFilter.js"></script>
+
+
+ <link rel="shortcut icon" href="img/favicon.png" type="image/png"/>
+ <link href="css/login.css" rel="stylesheet" type="text/css" />
+ <link href="../webjars/jquery-ui/${jquery-ui.version}/jquery-ui.css" rel="stylesheet" type="text/css" />
+ <link href="../webjars/bootstrap/${bootstrap.version}/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
+ <link href="../webjars/bootstrap-select/${bootstrap-select.version}/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
+ <link href="../webjars/font-awesome/${font-awesome.version}/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
+ <link href="../webjars/ionicons/${ionicons.version}/css/ionicons.min.css" rel="stylesheet" type="text/css" />
+ <link href="../webjars/angular-ui-select/${angular-ui-select.version}/select.css" rel="stylesheet" type="text/css"/>
+ <link href="../webjars/angular-growl-2/${angular-growl-2.version}/angular-growl.css" rel="stylesheet" type="text/css"/>
+ <link href="../webjars/select2/${select2.version}/select2.css" rel="stylesheet" type="text/css"/>
+ <link href="css/app.css" rel="stylesheet" type="text/css" />
+ <link href="css/login.css" rel="stylesheet" type="text/css" />
+ <link href="css/editUser.css" rel="stylesheet" type="text/css" />
+
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/app.js b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
new file mode 100644
index 0000000..1a53f00
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/app.js
@@ -0,0 +1,283 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ **/
+
+'use strict';
+
+angular.module('home', []);
+angular.module('login', []);
+angular.module('language', []);
+angular.module('self', []);
+
+// Declare app level module which depends on views, and components
+var app = angular.module('SyncopeEnduserApp', [
+ 'ui.router',
+ 'ui.bootstrap',
+ 'ui.select',
+ 'ngSanitize',
+ 'ngAnimate',
+ 'ngResource',
+ 'ngCookies',
+ 'angular-growl',
+ 'home',
+ 'login',
+ 'language',
+ 'self'
+]);
+
+app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider', 'growlProvider',
+ function ($stateProvider, $urlRouterProvider, $httpProvider, growlProvider) {
+ // route configuration
+ $stateProvider
+ .state('home', {
+ url: '/',
+ templateUrl: 'views/self.html'
+ })
+ .state('self', {
+ url: '/self',
+ templateUrl: 'views/self.html'
+ })
+ .state('user-self-update', {
+ url: '/user-self-update',
+ templateUrl: 'views/home.html',
+ controller: 'HomeController',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ .state('create', {
+ url: '/self/create',
+ templateUrl: 'views/editUser.html'
+ })
+ // nested states
+ // each of these sections will have their own view
+ // url will be nested (/self/create)
+ .state('create.credentials', {
+ url: '/credentials',
+ templateUrl: 'views/user-credentials.html'
+ })
+ .state('create.plainSchemas', {
+ url: '/plainSchemas',
+ templateUrl: 'views/user-plain-schemas.html'
+ })
+ .state('create.derivedSchemas', {
+ url: '/derivedSchemas',
+ templateUrl: 'views/user-derived-schemas.html'
+ })
+ .state('create.virtualSchemas', {
+ url: '/virtualSchemas',
+ templateUrl: 'views/user-virtual-schemas.html'
+ })
+ // url will be /self/create/schema
+ .state('create.groups', {
+ url: '/groups',
+ templateUrl: 'views/user-groups.html'
+ })
+ .state('create.resources', {
+ url: '/resources',
+ templateUrl: 'views/user-resources.html'
+ })
+ .state('update', {
+ url: '/self/update',
+ templateUrl: 'views/editUser.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ // nested states
+ // each of these sections will have their own view
+ // url will be nested (/self/create)
+ .state('update.credentials', {
+ url: '/credentials',
+ templateUrl: 'views/user-credentials.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ .state('update.plainSchemas', {
+ url: '/plainSchemas',
+ templateUrl: 'views/user-plain-schemas.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ .state('update.derivedSchemas', {
+ url: '/derivedSchemas',
+ templateUrl: 'views/user-derived-schemas.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ .state('update.virtualSchemas', {
+ url: '/virtualSchemas',
+ templateUrl: 'views/user-virtual-schemas.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ // url will be /self/create/schema
+ .state('update.groups', {
+ url: '/groups',
+ templateUrl: 'views/user-groups.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ })
+ .state('update.resources', {
+ url: '/resources',
+ templateUrl: 'views/user-resources.html',
+ resolve: {
+ 'authenticated': function (AuthenticationHelper) {
+ return AuthenticationHelper.authenticated();
+ }
+ }
+ });
+
+ // catch all other routes
+ // send users to the home page
+ $urlRouterProvider.otherwise('/');
+
+ // HTTP service configuration
+ $httpProvider.defaults.withCredentials = true;
+
+ $httpProvider.interceptors.push(function ($q, $rootScope, $location) {
+ var numLoadings = 0;
+ return {
+// 'request': function (config) {
+// numLoadings++;
+// // Show loader
+// if (config.url.indexOf("skipLoader=true") == -1) {
+// $rootScope.$broadcast("loader_show");
+// }
+// return config || $q.when(config);
+// },
+// 'response': function (response) {
+// if ((--numLoadings) === 0) {
+// // Hide loader
+// $rootScope.$broadcast("loader_hide");
+// }
+// return response || $q.when(response);
+// },
+ 'responseError': function (response) {
+ if (response.config.url.indexOf("acceptError=true") == -1) {
+ var status = response.status;
+ if (status == 401) {
+ console.log("ERROR " + status);
+// $location.path("/self");
+ }
+ if (status == 403) {
+ console.log("UNAUTHORIZED " + status);
+// $location.path("/self");
+ }
+ if (status == 400 || status == 404 || status == 412 || status == 500) {
+// if (response.data.validationErrors != undefined) {
+// for (var i in response.data.validationErrors) {
+// $rootScope.$broadcast('growlMessage', {text: response.data.validationErrors[i] || '', severity: 'error'});
+// }
+// } else if (response.data.message != undefined) {
+// $rootScope.$broadcast('growlMessage', {text: response.data.message || '', severity: 'error'})
+// }
+ console.log("GENERIC ERROR " + status);
+ }
+ }
+ return $q.reject(response);
+ }
+ };
+ });
+
+ growlProvider.globalTimeToLive(10000);
+ growlProvider.globalPosition('bottom-left');
+ growlProvider.globalInlineMessages(true);
+ growlProvider.globalDisableIcons(true);
+ //to enable html in growl
+// growlProvider.globalEnableHtml(true);
+ }]);
+
+app.run(['$rootScope', '$location', '$cookies', '$state',
+ function ($rootScope, $location, $cookies, $state) {
+ // main program
+ // keep user logged in after page refresh
+ // check if user is logged or not
+ $rootScope.currentUser = $cookies.get('currentUser') || null;
+//If the route change failed due to authentication error, redirect them out
+ $rootScope.$on('$routeChangeError', function (event, current, previous, rejection) {
+ if (rejection === 'Not Authenticated') {
+ $location.path('/self');
+ }
+ });
+
+// $rootScope.$on('success', function (event, args) {
+// console.log("IN CONFIG EVENTO: ", event);
+// $rootScope.$broadcast("error", "success");
+// });
+
+ $rootScope.$on('$stateChangeSuccess', function (event, toState) {
+ if (toState.name === 'create') {
+ $state.go('create.credentials');
+ } else if (toState.name === 'update') {
+ $state.go('update.credentials');
+ }
+ });
+// $rootScope.$on('$locationChangeStart', function (event, next, current) {
+// // redirect to login page if not logged in
+// if ($location.path() !== '/self' && !$rootScope.globals.currentUser) {
+// $location.path('/self');
+// }
+// });
+ }]);
+
+app.controller('ApplicationController', function ($scope) {
+// DO NOTHING
+// $scope.$on('success', function (event, args) {
+// console.log("IN CONFIG EVENTO: ", event)
+// $scope.$broadcast("error", "success");
+// });
+});
+
+app.factory('AuthenticationHelper', ['$q', '$rootScope',
+ function ($q, $rootScope) {
+ return {
+ authenticated: function () {
+
+ var currentUser = $rootScope.currentUser;
+
+ console.log("AuthenticationHelper, currentUser: ", currentUser);
+
+ if (angular.isDefined(currentUser) && currentUser) {
+ return true;
+ } else {
+ console.log("NOT AUTHENTICATED, REDIRECT TO LOGIN PAGE");
+ return $q.reject('Not Authenticated');
+ }
+ }
+ };
+ }]);
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js
new file mode 100644
index 0000000..bf86413
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/HomeController.js
@@ -0,0 +1,39 @@
+/**
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ **/
+
+'use strict';
+
+angular.module("home").controller("HomeController", ['$scope', '$http', '$location', function ($scope, $http, $location) {
+ $scope.title = 'Hello world!';
+ $scope.subtitle = 'Hello world SUBTITLE!';
+ $scope.name = "";
+
+// check if user is logged or not, check session variables: if user isn't logged redirect to login page
+
+ console.log("SONO IN HomeController");
+
+// var isLogged = false;
+// if (!isLogged) {
+// console.log("REDIRECT TO LOGIN PAGE");
+//// window.location = "./self.html";
+// $location.path("/self");
+// }
+
+
+ }]);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LanguageController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LanguageController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LanguageController.js
new file mode 100644
index 0000000..9e1fa6c
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LanguageController.js
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('language')
+ .controller('LanguageController', function ($scope) {
+
+ $scope.languages = {
+ availableLanguages: [
+ {id: '1', name: 'Italiano'},
+ {id: '2', name: 'English'},
+ {id: '3', name: 'Portugese'}
+ ],
+ selectedLanguage: {id: '2', name: 'English'}
+ };
+
+ $scope.init = function () {
+// MainService.settings().then(function (response) {
+// $scope.mainSettings = response;
+// });
+
+ console.log("Init language controller");
+ };
+
+ $scope.changeLanguage = function (language) {
+
+ console.log("Language changed to: ", language);
+
+ $scope.languages.selectedLanguage = language;
+
+// $translate.use(langKey);
+// LanguageService.switchLocale.query({language: langKey}, {}, function (response) {
+// $scope.selectedLanguage.locale = langKey;
+// });
+ };
+
+ this.retrieveLanguages = function () {
+// LanguageService.language.query({}, function (response) {
+// $scope.languages = response;
+// });
+ console.log("Retriebìving available languages");
+ };
+
+
+ this.retrieveLanguages();
+
+
+ });
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
new file mode 100644
index 0000000..c962571
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module("login").controller("LoginController", ['$scope', '$rootScope', '$http', '$location', '$cookies',
+ 'AuthService', 'growl', function ($scope, $rootScope, $http, $location, $cookies, AuthService, growl) {
+
+ $scope.credentials = {
+ username: '',
+ password: '',
+ errorMessage: ''
+ };
+
+ $scope.login = function (credentials) {
+
+ console.log("CREDENTIALS FROM PAGE: ", credentials);
+ console.log("AUTHSERVICE: ", AuthService);
+
+ AuthService.login($scope.credentials).then(function (user) {
+ console.log("LOGIN SUCCESS FOR: ", user);
+ console.log("DOPO AVER SETTATO CURRENT USER: ", $rootScope.currentUser);
+ console.log("COOKIE CURRENT USER: ", $cookies.get('currentUser'));
+ // reset error message
+ $scope.credentials.errorMessage = '';
+ // got to update page
+ $location.path("/self/update");
+ }, function (response) {
+ console.log("LOGIN FAILED: ", response);
+ $scope.credentials.errorMessage = "Login failed: " + response;
+ growl.error($scope.credentials.errorMessage, {referenceId: 1});
+ });
+ };
+
+ $scope.logout = function () {
+
+ console.log("PERFORMING LOGOUT");
+
+ AuthService.logout().then(function (response) {
+ console.log("LOGOUT SUCCESS: ", response);
+ }, function () {
+ console.log("LOGOUT FAILED");
+ });
+ };
+
+ $scope.isLogged = function () {
+ return angular.isDefined($rootScope.currentUser) && $rootScope.currentUser;
+ };
+
+ $scope.selfCreate = function () {
+ $location.path("/self/create");
+ };
+
+ $scope.passwordReset = function () {
+ // TODO
+ console.log("NOT YET IMPLEMENTED")
+ };
+
+ $scope.errorAPI = function () {
+ $http.get("/syncope-enduser/api/error").success(function (data) {
+ console.log("errorAPI response: ", data);
+ });
+ };
+
+ $scope.sampleAPI = function () {
+ $http.get("/syncope-enduser/api/user-self").success(function (data) {
+ console.log("sampleAPI response: ", data);
+ });
+ };
+
+ $scope.schemaAPI = function () {
+ $http.get("/syncope-enduser/api/schema").success(function (data) {
+ console.log("schemaAPI response: ", data);
+ });
+ };
+
+ }]);
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
new file mode 100644
index 0000000..892de21
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module("self").controller("UserController", ['$scope', '$rootScope', '$location', 'AuthService',
+ 'UserSelfService', 'SchemaService', 'RealmService', 'SecurityQuestionService', 'growl', function ($scope, $rootScope,
+ $location, AuthService, UserSelfService, SchemaService, RealmService, SecurityQuestionService, growl) {
+
+ $scope.user = {};
+ $scope.confirmPassword = {
+ value: ''
+ };
+ $scope.userFormValid = false;
+ $scope.createMode = $location.path().indexOf("/self/create") > -1;
+
+ $scope.availableRealms = [];
+ $scope.availableSecurityQuestions = [];
+
+ $scope.initialSecurityQuestion = undefined;
+
+ $scope.initUser = function () {
+
+ $scope.dynamicForm = {
+ plainSchemas: [],
+ derSchemas: [],
+ virSchemas: [],
+ selectedDerSchemas: [],
+ selectedVirSchemas: [],
+ errorMessage: '',
+ attributeTable: {}
+ };
+
+
+ var initSchemas = function () {
+ // initialization is done here synchronously to have all schema fields populated correctly
+ SchemaService.getUserSchemas().then(function (schemas) {
+ $scope.dynamicForm.plainSchemas = schemas.plainSchemas;
+ $scope.dynamicForm.derSchemas = schemas.derSchemas;
+ $scope.dynamicForm.virSchemas = schemas.virSchemas;
+
+ // initialize plain attributes
+ for (var i = 0; i < schemas.plainSchemas.length; i++) {
+
+ var plainSchemaKey = schemas.plainSchemas[i].key;
+
+ if (!$scope.user.plainAttrs[plainSchemaKey]) {
+
+ $scope.user.plainAttrs[plainSchemaKey] = {
+ schema: plainSchemaKey,
+ values: [],
+ readonly: schemas.plainSchemas[i].readonly
+ };
+
+ // initialize multivalue schema and support table: create mode, only first value
+ if (schemas.plainSchemas[i].multivalue) {
+ $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
+ fields: [schemas.plainSchemas[i].key + "_" + 0]
+ };
+ }
+ } else {
+ // initialize multivalue schema and support table: update mode, all provided values
+ if (schemas.plainSchemas[i].multivalue) {
+ $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
+ fields: [schemas.plainSchemas[i].key + "_" + 0]
+ };
+ // add other values
+ for (var j = 1; j < $scope.user.plainAttrs[plainSchemaKey].values.length; j++) {
+ $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key].fields.push(schemas.plainSchemas[i].key + "_" + j);
+ }
+ }
+ }
+ }
+
+ // initialize derived attributes
+ for (var i = 0; i < schemas.derSchemas.length; i++) {
+
+ var derSchemaKey = schemas.derSchemas[i].key;
+
+ if ($scope.user.derAttrs[derSchemaKey]) {
+ $scope.dynamicForm.selectedDerSchemas.push(schemas.derSchemas[i]);
+ }
+ }
+
+ // initialize virtual attributes
+ for (var i = 0; i < schemas.virSchemas.length; i++) {
+
+ var virSchemaKey = schemas.virSchemas[i].key;
+
+ if ($scope.user.virAttrs[virSchemaKey]) {
+ $scope.dynamicForm.selectedVirSchemas.push(schemas.virSchemas[i]);
+ }
+ }
+
+ }, function () {
+ console.log("Error retrieving user schemas");
+ });
+ console.log("USER WITH ATTRTO: ", $scope.user);
+
+ };
+
+ var initSecurityQuestions = function () {
+ SecurityQuestionService.getAvailableSecurityQuestions().then(function (response) {
+ $scope.availableSecurityQuestions = response;
+ }, function () {
+ console.log("Error");
+ });
+ };
+
+ var initRealms = function () {
+ $scope.availableRealms = RealmService.getAvailableRealmsStub();
+ };
+
+ var initUserRealm = function () {
+ $scope.user.realm = RealmService.getUserRealm();
+ };
+
+
+ var readUser = function () {
+ UserSelfService.read().then(function (response) {
+ $scope.user = response;
+ $scope.user.password = undefined;
+ $scope.initialSecurityQuestion = $scope.user.securityQuestion;
+ }, function () {
+ console.log("Error");
+ });
+ };
+
+ if ($scope.createMode) {
+
+ $scope.user = {
+ username: '',
+ password: '',
+ realm: '',
+ securityQuestion: undefined,
+ securityAnswer: '',
+ plainAttrs: {},
+ derAttrs: {},
+ virAttrs: {}
+ };
+
+ // retrieve user realm or all available realms
+ initUserRealm();
+
+ } else {
+
+ // read user from syncope core
+ readUser();
+ // read user security question
+
+ }
+
+ initRealms();
+ //retrieve security available questions
+ initSecurityQuestions();
+ // initialize user attributes starting from any object schemas
+ initSchemas();
+
+ };
+
+ $scope.saveUser = function (user) {
+ console.log("Save user: ", user);
+
+ if ($scope.createMode) {
+
+ UserSelfService.create(user).then(function (response) {
+ console.log("Created user: ", response);
+ growl.success("User " + $scope.user.username + " successfully created", {referenceId: 1});
+ $location.path('/self');
+ }, function (response) {
+ console.log("Error during user creation: ", response);
+ growl.error("Error: " + response, {referenceId: 2});
+ });
+
+ } else {
+
+ UserSelfService.update(user).then(function (response) {
+ console.log("Updated user: ", response);
+ growl.success("User " + $scope.user.username + " successfully updated", {referenceId: 1});
+ $location.path('/self');
+ }, function (response) {
+ console.log("Error during user update: ", response);
+ growl.error("Error: " + response, {referenceId: 2});
+ });
+ }
+ };
+
+
+
+ }]);
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js
new file mode 100644
index 0000000..6a00507
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicAttribute.js
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+angular.module('self')
+ .directive('dynamicAttribute', function ($filter) {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/dynamicAttribute.html',
+ scope: {
+ schema: "=",
+ index: "=",
+ user: "="
+ },
+ controller: function ($scope, $element, $window) {
+ $scope.initAttribute = function (schema, index) {
+
+ switch (schema.type) {
+ case "Long":
+ case "Double":
+ $scope.user.plainAttrs[schema.key].values[index] = Number($scope.user.plainAttrs[schema.key].values[index])
+ || undefined;
+ break;
+ case "Enum":
+ $scope.enumerationValues = [];
+ var enumerationValuesSplitted = schema.enumerationValues.toString().split(";");
+ for (var i = 0; i < enumerationValuesSplitted.length; i++) {
+ $scope.enumerationValues.push(enumerationValuesSplitted[i]);
+ }
+ $scope.user.plainAttrs[schema.key].values[index] = $scope.user.plainAttrs[schema.key].values[index]
+ || $scope.enumerationValues[0];
+ break;
+ case "Binary":
+
+ $scope.userFile = $scope.userFile || '';
+ //for multivalue fields
+// $scope.fileInputId = "fileInputId_" + index;
+
+ $element.bind("change", function (changeEvent) {
+ $scope.$apply(function () {
+ var reader = new FileReader();
+ var file = changeEvent.target.files[0];
+ $scope.userFile = file.name;
+ reader.onload = function (readerEvt) {
+ var binaryString = readerEvt.target.result;
+ $scope.user.plainAttrs[schema.key].values[index] = btoa(binaryString);
+ };
+ reader.readAsBinaryString(file);
+ });
+ });
+
+ $scope.download = function () {
+ var byteString = atob($scope.user.plainAttrs[schema.key].values[index]);
+
+ var ab = new ArrayBuffer(byteString.length);
+ var ia = new Uint8Array(ab);
+ for (var i = 0; i < byteString.length; i++) {
+ ia[i] = byteString.charCodeAt(i);
+ }
+
+ var blob = new Blob([ia], {type: schema.mimeType});
+
+ saveAs(blob, schema.key);
+ };
+ $scope.remove = function () {
+ $scope.user.plainAttrs[schema.key].values.splice(index, 1);
+ $scope.userFile = '';
+ $("#fileInput").replaceWith($("#fileInput").clone(true));
+ };
+ break;
+ case "Date":
+
+ $scope.selectedDate = $scope.user.plainAttrs[schema.key].values[index];
+ $scope.format = $scope.schema.conversionPattern;
+ $scope.includeTimezone = false;
+ if ($scope.schema.conversionPattern.indexOf(".SSS") > -1) {
+ $scope.format = $scope.format.replace(".SSS", ".sss");
+ }
+ if ($scope.schema.conversionPattern.indexOf("Z") > -1) {
+ $scope.includeTimezone = true;
+ $scope.format = $scope.format.replace("Z", "");
+ }
+ if ($scope.schema.conversionPattern.indexOf("\'") > -1) {
+ $scope.format = $scope.format.replace(new RegExp("\'", "g"), "");
+ }
+
+ $scope.bindDateToModel = function (selectedDate, format) {
+ var newFormat = $scope.includeTimezone ? format.concat(" Z") : format;
+ if (selectedDate) {
+ selectedDate = $filter('date')(selectedDate, newFormat);
+ var dateGood = selectedDate.toString();
+ $scope.user.plainAttrs[schema.key].values[index] = dateGood;
+ } else {
+ $scope.user.plainAttrs[schema.key].values[index] = selectedDate;
+ }
+ };
+
+ $scope.clear = function () {
+ $scope.user.plainAttrs[schema.key].values[index] = null;
+ };
+
+ // Disable weekend selection
+ $scope.disabled = function (date, mode) {
+ // example if you want to disable weekends
+ // return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6));
+ return false;
+ };
+
+ $scope.toggleMin = function () {
+ $scope.minDate = $scope.minDate ? null : new Date();
+ };
+
+ $scope.maxDate = new Date(2050, 5, 22);
+
+ $scope.open = function ($event) {
+ $scope.status.opened = true;
+ };
+
+ $scope.setDate = function (year, month, day) {
+ $scope.user.plainAttrs[schema.key].values[index] = new Date(year, month, day);
+ };
+
+ $scope.dateOptions = {
+ startingDay: 1
+ };
+
+ $scope.status = {
+ opened: false
+ };
+
+ var tomorrow = new Date();
+ tomorrow.setDate(tomorrow.getDate() + 1);
+ var afterTomorrow = new Date();
+ afterTomorrow.setDate(tomorrow.getDate() + 2);
+ $scope.events =
+ [
+ {
+ date: tomorrow,
+ status: 'full'
+ },
+ {
+ date: afterTomorrow,
+ status: 'partially'
+ }
+ ];
+
+ $scope.getDayClass = function (date, mode) {
+ if (mode === 'day') {
+ var dayToCheck = new Date(date).setHours(0, 0, 0, 0);
+
+ for (var i = 0; i < $scope.events.length; i++) {
+ var currentDay = new Date($scope.events[i].date).setHours(0, 0, 0, 0);
+
+ if (dayToCheck === currentDay) {
+ return $scope.events[i].status;
+ }
+ }
+ }
+
+ };
+ break;
+
+ case "Boolean":
+ $scope.user.plainAttrs[schema.key].values[index] =
+ Boolean($scope.user.plainAttrs[schema.key].values[index]) || false;
+ break;
+
+ }
+ }
+ ;
+ },
+ replace: true
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js
new file mode 100644
index 0000000..887b5c6
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicDerivedAttributes.js
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+angular.module('self')
+ .directive('dynamicDerivedAttributes', function () {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/dynamicDerivedAttributes.html',
+ scope: {
+ dynamicForm: "=form",
+ user: "="
+ },
+ controller: function ($scope) {
+
+ $scope.addDerivedAttribute = function (item, model) {
+ var derSchemaKey = item.key;
+ console.log("ADDING DERIVED item: ", derSchemaKey);
+ $scope.user.derAttrs[derSchemaKey] = {
+ schema: derSchemaKey,
+ values: [],
+ readonly: false
+ };
+
+ };
+
+ $scope.removeDerivedAttribute = function (item, model) {
+ var derSchemaKey = item.key;
+ console.log("REMOVING DERIVED item: ", derSchemaKey);
+ delete $scope.user.derAttrs[derSchemaKey];
+
+ };
+
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
new file mode 100644
index 0000000..1a0a4c3
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+angular.module('self')
+ .directive('dynamicPlainAttributes', function (SchemaService) {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/dynamicPlainAttributes.html',
+ scope: {
+ dynamicForm: "=form",
+ user: "="
+ },
+ controller: function ($scope) {
+
+ $scope.addAttributeField = function (plainSchemaKey) {
+ console.log("ADDING: ", plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
+ $scope.dynamicForm.attributeTable[plainSchemaKey].fields.push(plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
+ };
+
+ $scope.removeAttributeField = function (plainSchemaKey, index) {
+ console.log("REMOVING FROM: " + plainSchemaKey + " ATTRIBUTE INDEX: " + index);
+ $scope.dynamicForm.attributeTable[plainSchemaKey].fields.splice(index, 1);
+ // clean user model
+ $scope.user.plainAttrs[plainSchemaKey].values.splice(index, 1);
+ };
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js
new file mode 100644
index 0000000..62c1591
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicVirtualAttributes.js
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+angular.module('self')
+ .directive('dynamicVirtualAttributes', function () {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/dynamicVirtualAttributes.html',
+ scope: {
+ dynamicForm: "=form",
+ user: "="
+ },
+ controller: function ($scope) {
+
+ $scope.addVirtualAttribute = function (item, model) {
+ var virSchemaKey = item.key;
+ console.log("ADDING VIRTUAL item: ", virSchemaKey);
+ $scope.user.virAttrs[virSchemaKey] = {
+ schema: virSchemaKey,
+ values: [],
+ readonly: false
+ };
+
+ };
+
+ $scope.removeVirtualAttribute = function (item, model) {
+ var virSchemaKey = item.key;
+ console.log("REMOVING VIRTUAL item: ", virSchemaKey);
+ delete $scope.user.virAttrs[virSchemaKey];
+
+ };
+
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/equals.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/equals.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/equals.js
new file mode 100644
index 0000000..54c2022
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/equals.js
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+angular.module('self')
+ .directive('equals', function () {
+ return {
+ restrict: 'A',
+ require: '?ngModel',
+ link: function (scope, elem, attrs, ngModel) {
+ if (!ngModel)
+ return; // do nothing if no ng-model
+
+ // watch own value and re-validate on change
+ scope.$watch(attrs.ngModel, function () {
+ validate();
+ });
+
+ // observe the other value and re-validate on change
+ attrs.$observe('equals', function (val) {
+ validate();
+ });
+
+ var validate = function () {
+ // values
+ var val1 = ngModel.$viewValue;
+ var val2 = attrs.equals;
+
+ // set validity
+ ngModel.$setValidity('equals', !val1 || !val2 || val1 === val2);
+ };
+ }
+ };
+ });
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js
new file mode 100644
index 0000000..603fb34
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/loader.js
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('SyncopeEnduserApp')
+ .directive("loader", function ($rootScope) {
+ return function ($scope, element, attrs) {
+ $scope.$on("loader_show", function () {
+ return element.show();
+ });
+ return $scope.$on("loader_hide", function () {
+ return element.hide();
+ });
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtons.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtons.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtons.js
new file mode 100644
index 0000000..ff3eebf
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/navigationButtons.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+angular.module('self')
+ .directive('navigationButtons', function () {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/navigationButtons.html',
+ scope: {
+ next: "@",
+ previous: "@"
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js
new file mode 100644
index 0000000..4bf52b2
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/passwordStrengthEstimator.js
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict'
+
+angular.module('self', [])
+ .directive('checkStrength', function () {
+ return {
+ replace: false,
+ restrict: 'EACM',
+ link: function (scope, iElement, iAttrs) {
+
+ var strength = {
+ colors: ['#F00', '#F90', '#FF0', '#9F0', '#0F0'],
+ mesureStrength: function (p) {
+
+ var _force = 0;
+ var _regex = /[$-/:-?{-~!"^_`\[\]]/g;
+
+ var _lowerLetters = /[a-z]+/.test(p);
+ var _upperLetters = /[A-Z]+/.test(p);
+ var _numbers = /[0-9]+/.test(p);
+ var _symbols = _regex.test(p);
+
+ var _flags = [_lowerLetters, _upperLetters, _numbers, _symbols];
+ var _passedMatches = $.grep(_flags, function (el) {
+ return el === true;
+ }).length;
+
+ _force += 2 * p.length + ((p.length >= 10) ? 1 : 0);
+ _force += _passedMatches * 10;
+
+ // penality (short password)
+ _force = (p.length <= 6) ? Math.min(_force, 10) : _force;
+
+ // penality (poor variety of characters)
+ _force = (_passedMatches == 1) ? Math.min(_force, 10) : _force;
+ _force = (_passedMatches == 2) ? Math.min(_force, 20) : _force;
+ _force = (_passedMatches == 3) ? Math.min(_force, 40) : _force;
+
+ return _force;
+
+ },
+ getColor: function (s) {
+
+ var idx = 0;
+ if (s <= 10) {
+ idx = 0;
+ }
+ else if (s <= 20) {
+ idx = 1;
+ }
+ else if (s <= 30) {
+ idx = 2;
+ }
+ else if (s <= 40) {
+ idx = 3;
+ }
+ else {
+ idx = 4;
+ }
+
+ return {idx: idx + 1, col: this.colors[idx]};
+
+ }
+ };
+
+ scope.$watch(iAttrs.checkStrength, function () {
+ if (scope.pw === '') {
+ iElement.css({"display": "none"});
+ } else {
+ var strength = strength.mesureStrength(scope.pw);
+ var c = strength.getColor(strength);
+ iElement.css({"display": "inline"});
+ iElement.children('li')
+ .css({"background": "#DDD"})
+ .slice(0, c.idx)
+ .css({"background": c.col});
+ }
+ });
+
+ },
+ template: ''
+ };
+ });
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/filters/propsFilter.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/filters/propsFilter.js b/client/enduser/src/main/resources/META-INF/resources/app/js/filters/propsFilter.js
new file mode 100644
index 0000000..a092d0c
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/filters/propsFilter.js
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict'
+
+angular.module("self")
+ .filter('propsFilter', function () {
+ return function (items, props) {
+ var out = [];
+
+ if (angular.isArray(items)) {
+ items.forEach(function (item) {
+ var itemMatches = false;
+
+ var keys = Object.keys(props);
+ for (var i = 0; i < keys.length; i++) {
+ var prop = keys[i];
+ var text = props[prop].toLowerCase();
+ if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
+ itemMatches = true;
+ break;
+ }
+ }
+
+ if (itemMatches) {
+ out.push(item);
+ }
+ });
+ } else {
+ // Let the output be the input untouched
+ out = items;
+ }
+
+ return out;
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/services/authService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/authService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/authService.js
new file mode 100644
index 0000000..3c3f7af
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/authService.js
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('login')
+ .factory('AuthService', ['$rootScope', '$resource', '$q', '$http', '$cookies',
+ function ($rootScope, $resource, $q, $http, $cookies) {
+
+ var authService = {};
+
+ var clearUserCookie = function () {
+ $rootScope.currentUser = null;
+ $cookies.remove('currentUser');
+ };
+
+ authService.login = function (credentials) {
+ return $http
+ .post('/syncope-enduser/api/login', credentials)
+ .then(function (response) {
+ var username = response.data;
+ $cookies.put('currentUser', username);
+ $rootScope.currentUser = username;
+ return username;
+ }, function (response) {
+ clearUserCookie();
+ console.log("Something went wrong during login, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ authService.logout = function () {
+ return $http
+ .get('/syncope-enduser/api/logout')
+ .then(function (response) {
+ clearUserCookie();
+ return response;
+ }, function (response) {
+ clearUserCookie();
+ console.log("Something went wrong during logout, exit with status: ", response);
+ });
+ };
+
+ return authService;
+// return {
+// login: $resource('/syncope-enduser/api/login', {}, {
+// do: {method: 'POST', params: {}, isArray: false}
+// })
+// };
+// return {
+// logout: $resource('/cradleDashboard/api/logout', {}, {
+// query: {method: 'GET', params: {}, isArray: false}
+// })
+// };
+
+ }]);
+
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/services/realmService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/realmService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/realmService.js
new file mode 100644
index 0000000..356dc87
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/realmService.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('self')
+ .factory('RealmService', ['$resource', '$q', '$http',
+ function ($resource, $q, $http) {
+
+ var realmService = {};
+
+ realmService.getAvailableRealmsStub = function () {
+ return ["/"];
+ };
+
+ realmService.getAvailableRealms = function () {
+ return $http.get("/syncope-enduser/api/realms")
+ .then(function (response) {
+ console.log("realms response: ", response);
+ return response.data;
+ }, function (response) {
+ console.log("Something went wrong during realms retrieval, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ realmService.getUserRealm = function () {
+ return "/";
+ };
+ return realmService;
+ }]);
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
new file mode 100644
index 0000000..be9f510
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('self')
+ .factory('SchemaService', ['$resource', '$q', '$http',
+ function ($resource, $q, $http) {
+
+ var schemaService = {};
+
+ schemaService.getUserSchemas = function () {
+
+ return $http.get("/syncope-enduser/api/schemas")
+ .then(function (response) {
+ console.log("schemaAPI response: ", response);
+ return response.data;
+ }, function (response) {
+ console.log("Something went wrong during schema retrieval, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+ return schemaService;
+ }]);
+
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/services/securityQuestionService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/securityQuestionService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/securityQuestionService.js
new file mode 100644
index 0000000..ff91f18
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/securityQuestionService.js
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('self')
+ .factory('SecurityQuestionService', ['$resource', '$q', '$http',
+ function ($resource, $q, $http) {
+
+ var securityQuestionService = {};
+
+ securityQuestionService.getAvailableSecurityQuestions = function () {
+ return $http.get("/syncope-enduser/api/securityQuestions")
+ .then(function (response) {
+ console.log("security questions response: ", response);
+ return response.data;
+ }, function (response) {
+ console.log("Something went wrong during security questions retrieval, exit with status: ",
+ response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ return securityQuestionService;
+ }]);
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/js/services/userSelfService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/userSelfService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/userSelfService.js
new file mode 100644
index 0000000..3a99e7f
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/userSelfService.js
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+'use strict';
+
+angular.module('login')
+ .factory('UserSelfService', ['$resource', '$q', '$http',
+ function ($resource, $q, $http) {
+
+ var userSelfService = {};
+
+ userSelfService.read = function () {
+ return $http
+ .get('/syncope-enduser/api/self/read')
+ .then(function (response) {
+ console.log("response read: ", response.data);
+ return response.data;
+ }, function (response) {
+ console.log("Something went wrong during user self read, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ userSelfService.create = function (user) {
+ return $http
+ .post('/syncope-enduser/api/self/create', user)
+ .then(function (response) {
+ console.log("response save: ", response)
+ var username = response;
+ }, function (response) {
+ console.log("Something went wrong during user self creation, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ userSelfService.update = function (user) {
+ return $http
+ .post('/syncope-enduser/api/self/update', user)
+ .then(function (response) {
+ var username = response;
+ }, function (response) {
+ console.log("Something went wrong during user self update, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ userSelfService.passwordReset = function () {
+ };
+
+ return userSelfService;
+ }]);
+
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html
new file mode 100644
index 0000000..9c6b1d9
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicAttribute.html
@@ -0,0 +1,58 @@
+<div ng-switch="schema.type" >
+ <input ng-switch-when="String" class="form-control" type="text"
+ ng-model="user.plainAttrs[schema.key].values[index]"
+ ng-required="schema.mandatoryCondition"
+ ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/>
+ <input ng-switch-when="Encrypted" class="form-control" type="text"
+ ng-model="user.plainAttrs[schema.key].values[index]"
+ ng-required="schema.mandatoryCondition"
+ ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/>
+ <div ng-switch-when="Boolean">
+ <input type="checkbox" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition"
+ ng-init="initAttribute(schema, index)" />
+ </div>
+ <input ng-switch-when="Long" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition"
+ ng-init="initAttribute(schema, index)" />
+ <input ng-switch-when="Double" class="form-control" type="number" ng-model="user.plainAttrs[schema.key].values[index]" ng-required="schema.mandatoryCondition"
+ ng-init="initAttribute(schema, index)" />
+ <p ng-switch-when="Date" class="input-group" >
+ <input type="text" class="form-control"
+ uib-datepicker-popup="{{format}}"
+ ng-model="selectedDate"
+ ng-change="bindDateToModel(selectedDate, format)"
+ min-date="minDate" max-date="maxDate"
+ is-open="status.opened" datepicker-options="dateOptions"
+ ng-required="schema.mandatoryCondition" close-text="Close" ng-init="initAttribute(schema, index)"/>
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
+ </span>
+ </p>
+
+ <div ng-switch-when="Enum" ng-init="initAttribute(schema, index)">
+ <select class="form-control"
+ ng-model="user.plainAttrs[schema.key].values[index]"
+ ng-required="schema.mandatoryCondition">
+ <option ng-repeat="value in enumerationValues" value="{{value}}">{{schema.enumerationKeys[$index] || value}}</option>
+ </select>
+ </div>
+
+ <div ng-switch-when="Binary" ng-init="initAttribute(schema, index)">
+ <div enctype="multipart/form-data" accept-charset="UTF-8">
+ <input id="fileInput" type="file" ng-required="schema.mandatoryCondition"/>
+ <button type="button" title="Download file" class="fileButton btn btn-default btn-sm" ng-click="download()">
+ <i class="glyphicon glyphicon-download" ></i>
+ </button>
+ <button type="button" class="fileButton btn btn-default btn-sm" title="Remove file" ng-click="remove()">
+ <i class="glyphicon glyphicon-remove-sign" ></i>
+ </button>
+ <h4><span class="label label-primary" ng-model="userFile">{{userFile}}</span></h4>
+ </div>
+
+ </div>
+
+ <input ng-switch-default class="form-control" type="text"
+ ng-model="user.plainAttrs[schema.key].values[index]"
+ ng-required="schema.mandatoryCondition"
+ ng-disabled="schema.readonly" ng-init="initAttribute(schema, index)"/>
+
+</div>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
new file mode 100644
index 0000000..9400877
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicDerivedAttributes.html
@@ -0,0 +1,21 @@
+<ui-select on-select="addDerivedAttribute($item, $model)" on-remove="removeDerivedAttribute($item, $model)" multiple
+ ng-model="dynamicForm.selectedDerSchemas" theme="select2" class="attribute-ui-select">
+ <ui-select-match placeholder="Select derived attribute...">{{$item.key}}</ui-select-match>
+ <ui-select-choices repeat="derSchema in dynamicForm.derSchemas | propsFilter: {key: $select.search}">
+ <div ng-bind-html="derSchema.key | highlight: $select.search"></div>
+ <small>
+ name: {{derSchema.key}}
+ expression: {{derSchema.expression}}
+ </small>
+ </ui-select-choices>
+</ui-select>
+
+<ul class="attribute-virtual-value-container">
+ <li class="attribute-virtual-value-field" ng-repeat="selectedDerSchema in dynamicForm.selectedDerSchemas| filter:q as results">
+ {{selectedDerSchema.key}}
+ <input style="font-weight: normal" class="form-control" type="text" ng-disabled="true" ng-model="user.derAttrs[selectedDerSchema.key].values[0]"/>
+ </li>
+ <li class="attribute-virtual-value-field" ng-if="results.length == 0">
+ <strong>No derived attributes selected...</strong>
+ </li>
+</ul>
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
new file mode 100644
index 0000000..074abbd
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicPlainAttributes.html
@@ -0,0 +1,22 @@
+<div id="attribute" class="form-group" ng-repeat="plainSchema in dynamicForm.plainSchemas">
+ <label for="plainSchema.key">{{plainSchema.key}} <span ng-if="Boolean(plainSchema.mandatoryCondition)">*</span></label>
+ <div ng-if="!plainSchema.multivalue">
+ <dynamic-attribute schema="plainSchema" user="user" index="0"></dynamic-attribute>
+ </div>
+
+ <div ng-if="plainSchema.multivalue">
+ <div ng-repeat="field in dynamicForm.attributeTable[plainSchema.key].fields track by $index" ng-model='dynamicForm.attributeTable[plainSchema.key].fields[$index]'>
+ <dynamic-attribute schema="plainSchema" user="user" index="$index"></dynamic-attribute>
+ <span>
+ <button class="btn btn-default btn-sm minus" ng-if="$index > 0" type="button" ng-click="removeAttributeField(plainSchema.key, $index)">
+ <i class="glyphicon glyphicon-minus" title="Remove value"></i>
+ </button>
+ </span>
+ </div>
+ <span>
+ <button class="btn btn-default btn-sm" type="button" ng-click="addAttributeField(plainSchema.key)">
+ <i class="glyphicon glyphicon-plus" title="Add value"></i>
+ </button>
+ </span>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
new file mode 100644
index 0000000..897eb2c
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/dynamicVirtualAttributes.html
@@ -0,0 +1,18 @@
+<ui-select on-select="addVirtualAttribute($item, $model)" on-remove="removeVirtualAttribute($item, $model)" multiple
+ ng-model="dynamicForm.selectedVirSchemas" theme="select2" ng-disabled="false" class="attribute-ui-select">
+ <ui-select-match placeholder="Select virtual attribute...">{{$item.key}}</ui-select-match>
+ <ui-select-choices repeat="virSchema in dynamicForm.virSchemas | propsFilter: {key: $select.search}">
+ <div ng-bind-html="virSchema.key | highlight: $select.search"></div>
+ </ui-select-choices>
+</ui-select>
+
+<ul class="attribute-virtual-value-container">
+ <li class="attribute-virtual-value-field" ng-repeat="selectedVirSchema in dynamicForm.selectedVirSchemas| filter:q as results">
+ {{selectedVirSchema.key}}
+ <input style="font-weight: normal" class="form-control" type="text" ng-disabled="selectedVirSchema.readonly"
+ ng-model="user.virAttrs[selectedVirSchema.key].values[0]"/>
+ </li>
+ <li class="attribute-virtual-value-field" ng-if="results.length == 0">
+ <strong>No virtual attributes selected...</strong>
+ </li>
+</ul>
\ No newline at end of file
[3/4] syncope git commit: SYNCOPE-701 first working implementation
Posted by an...@apache.org.
SYNCOPE-701 first working implementation
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/223a64e2
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/223a64e2
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/223a64e2
Branch: refs/heads/master
Commit: 223a64e26deff69a4ed8275d0f1348ca4e130a01
Parents: 764fa2e
Author: Andrea Patricelli <an...@tirasa.net>
Authored: Mon Oct 5 15:12:55 2015 +0200
Committer: Andrea Patricelli <an...@tirasa.net>
Committed: Fri Oct 30 10:26:17 2015 +0100
----------------------------------------------------------------------
client/enduser/pom.xml | 194 +++++++++
.../enduser/SyncopeEnduserApplication.java | 157 +++++++
.../client/enduser/SyncopeEnduserSession.java | 279 +++++++++++++
.../client/enduser/adapters/UserTOAdapter.java | 78 ++++
.../client/enduser/model/Credentials.java | 65 +++
.../client/enduser/model/SchemaResponse.java | 79 ++++
.../client/enduser/model/UserTORequest.java | 174 ++++++++
.../syncope/client/enduser/pages/HomePage.java | 35 ++
.../enduser/resources/AbstractBaseResource.java | 58 +++
.../client/enduser/resources/ErrorResource.java | 50 +++
.../client/enduser/resources/LoginResource.java | 84 ++++
.../enduser/resources/LogoutResource.java | 43 ++
.../enduser/resources/SchemaResource.java | 116 ++++++
.../resources/SecurityQuestionResource.java | 73 ++++
.../resources/UserSelfCreateResource.java | 97 +++++
.../enduser/resources/UserSelfReadResource.java | 66 +++
.../resources/UserSelfUpdateResource.java | 96 +++++
.../META-INF/resources/app/css/app.css | 28 ++
.../META-INF/resources/app/css/editUser.css | 253 ++++++++++++
.../META-INF/resources/app/css/login.css | 103 +++++
.../META-INF/resources/app/img/ajax-loader.gif | Bin 0 -> 1924 bytes
.../META-INF/resources/app/img/busy.gif | Bin 0 -> 2834 bytes
.../META-INF/resources/app/img/favicon.png | Bin 0 -> 641 bytes
.../META-INF/resources/app/img/logo-green.png | Bin 0 -> 12178 bytes
.../META-INF/resources/app/img/logo.png | Bin 0 -> 8913 bytes
.../resources/META-INF/resources/app/index.html | 116 ++++++
.../resources/META-INF/resources/app/js/app.js | 283 +++++++++++++
.../app/js/controllers/HomeController.js | 39 ++
.../app/js/controllers/LanguageController.js | 66 +++
.../app/js/controllers/LoginController.js | 93 +++++
.../app/js/controllers/UserController.js | 206 +++++++++
.../app/js/directives/dynamicAttribute.js | 190 +++++++++
.../js/directives/dynamicDerivedAttributes.js | 52 +++
.../app/js/directives/dynamicPlainAttributes.js | 45 ++
.../js/directives/dynamicVirtualAttributes.js | 52 +++
.../resources/app/js/directives/equals.js | 49 +++
.../resources/app/js/directives/loader.js | 32 ++
.../app/js/directives/navigationButtons.js | 31 ++
.../js/directives/passwordStrengthEstimator.js | 102 +++++
.../resources/app/js/filters/propsFilter.js | 52 +++
.../resources/app/js/services/authService.js | 74 ++++
.../resources/app/js/services/realmService.js | 47 +++
.../resources/app/js/services/schemaService.js | 42 ++
.../app/js/services/securityQuestionService.js | 41 ++
.../app/js/services/userSelfService.js | 69 ++++
.../resources/app/views/dynamicAttribute.html | 58 +++
.../app/views/dynamicDerivedAttributes.html | 21 +
.../app/views/dynamicPlainAttributes.html | 22 +
.../app/views/dynamicVirtualAttributes.html | 18 +
.../META-INF/resources/app/views/editUser.html | 73 ++++
.../resources/app/views/generic-error.html | 24 ++
.../META-INF/resources/app/views/home.html | 34 ++
.../resources/app/views/navigationButtons.html | 8 +
.../META-INF/resources/app/views/self.html | 131 ++++++
.../resources/app/views/user-credentials.html | 60 +++
.../app/views/user-derived-schemas.html | 37 ++
.../resources/app/views/user-groups.html | 37 ++
.../resources/app/views/user-plain-schemas.html | 37 ++
.../resources/app/views/user-resources.html | 28 ++
.../app/views/user-virtual-schemas.html | 37 ++
.../main/resources/META-INF/web-fragment.xml | 72 ++++
.../src/main/resources/enduser.properties | 30 ++
.../syncope/client/enduser/pages/HomePage.html | 22 +
.../enduser/SyncopeEnduserApplicationTest.java | 69 ++++
client/pom.xml | 1 +
.../syncope/common/lib/types/Entitlement.java | 10 -
.../syncope/core/logic/AnyTypeClassLogic.java | 4 +-
.../apache/syncope/core/logic/AnyTypeLogic.java | 4 +-
.../apache/syncope/core/logic/SchemaLogic.java | 2 +-
.../core/reference/AuthenticationITCase.java | 11 -
fit/enduser-reference/pom.xml | 413 +++++++++++++++++++
.../src/main/resources/context.xml | 23 ++
.../src/main/resources/enduser.properties | 30 ++
.../src/main/resources/log4j2.xml | 58 +++
.../src/main/webapp/WEB-INF/glassfish-web.xml | 25 ++
.../WEB-INF/jboss-deployment-structure.xml | 37 ++
.../src/main/webapp/WEB-INF/weblogic.xml | 35 ++
fit/pom.xml | 1 +
pom.xml | 89 +++-
79 files changed, 5343 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/pom.xml
----------------------------------------------------------------------
diff --git a/client/enduser/pom.xml b/client/enduser/pom.xml
new file mode 100644
index 0000000..a9dc260
--- /dev/null
+++ b/client/enduser/pom.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-client</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Client Enduser</name>
+ <description>Apache Syncope Client Enduser</description>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-enduser</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-misc</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket</artifactId>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket-extensions</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket-datetime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket-spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.wicket</groupId>
+ <artifactId>wicket-auth-roles</artifactId>
+ </dependency>
+
+ <!--AngularJS-->
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-route</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-resource</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-ui-router</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-animate</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-cookies</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-growl-2</artifactId>
+ </dependency>
+ <!--Bootstrap-->
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>font-awesome</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>bootstrap-select</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>bootstrap</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>ionicons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-ui-bootstrap</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>angular-ui-select</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>angular-sanitize</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>select2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars.bower</groupId>
+ <artifactId>FileSaver.js</artifactId>
+ </dependency>
+
+ <!--Jquery-->
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>jquery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>jquery-cookie</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>jquery-ui</artifactId>
+ </dependency>
+
+ <!--Logging-->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+
+ </build>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
new file mode 100644
index 0000000..4acc756
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser;
+
+import java.io.Serializable;
+import org.apache.syncope.client.enduser.pages.HomePage;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import org.apache.syncope.client.enduser.resources.ErrorResource;
+import org.apache.syncope.client.enduser.resources.LoginResource;
+import org.apache.syncope.client.enduser.resources.LogoutResource;
+import org.apache.syncope.client.enduser.resources.SchemaResource;
+import org.apache.syncope.client.enduser.resources.SecurityQuestionResource;
+import org.apache.syncope.client.enduser.resources.UserSelfCreateResource;
+import org.apache.syncope.client.enduser.resources.UserSelfReadResource;
+import org.apache.syncope.client.enduser.resources.UserSelfUpdateResource;
+import org.apache.wicket.Page;
+import org.apache.wicket.Session;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SyncopeEnduserApplication extends WebApplication implements Serializable {
+
+ private static final long serialVersionUID = -6445919351044845120L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserApplication.class);
+
+ public static final List<Locale> SUPPORTED_LOCALES = Collections.unmodifiableList(Arrays.asList(
+ new Locale[] {
+ Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR")
+ }));
+
+ @Override
+ protected void init() {
+ super.init();
+
+ LOG.debug("init SyncopeEnduserApplication");
+
+ // resource to provide login functionality managed by wicket
+ mountResource("/api/login", new ResourceReference("login") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new LoginResource();
+ }
+ });
+
+ // resource to provide logout functionality managed by wicket
+ mountResource("/api/logout", new ResourceReference("logout") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new LogoutResource();
+ }
+ });
+
+ // resource to retrieve info about logged user
+ mountResource("/api/self/read", new ResourceReference("userSelfRead") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new UserSelfReadResource();
+ }
+ });
+
+ // resource to provide user self create functionality managed by wicket
+ mountResource("/api/self/create", new ResourceReference("userSelfCreate") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new UserSelfCreateResource();
+ }
+ });
+
+ // resource to provide user self update functionality managed by wicket
+ mountResource("/api/self/update", new ResourceReference("userSelfUpdate") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new UserSelfUpdateResource();
+ }
+ });
+
+ mountResource("/api/schemas", new ResourceReference("schemas") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new SchemaResource();
+ }
+ });
+
+ mountResource("/api/securityQuestions", new ResourceReference("securityQuestions") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new SecurityQuestionResource();
+ }
+ });
+
+ mountResource("/api/error", new ResourceReference("error") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new ErrorResource();
+ }
+ });
+ }
+
+ @Override
+ public Class<? extends Page> getHomePage() {
+ return HomePage.class;
+ }
+
+ @Override
+ public Session newSession(final Request request, final Response response) {
+ return new SyncopeEnduserSession(request);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
new file mode 100644
index 0000000..c5abc1d
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MediaType;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.SyncopeTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.wicket.Session;
+import org.apache.wicket.protocol.http.WebSession;
+import org.apache.wicket.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Custom Syncope Enduser Session class.
+ */
+public class SyncopeEnduserSession extends WebSession {
+
+ private static final long serialVersionUID = 1284946129513378647L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserSession.class);
+
+ public static final List<Locale> SUPPORTED_LOCALES = Arrays.asList(new Locale[] {
+ Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR") });
+
+ protected static final String ENDUSER_PROPERTIES = "enduser.properties";
+
+ private String username;
+
+ private String password;
+
+ private String scheme;
+
+ private String host;
+
+ private String port;
+
+ private String rootPath;
+
+ private String anonymousUser;
+
+ private String anonymousKey;
+
+ private Boolean storePassword;
+
+ private String version;
+
+ private String license;
+
+ private final SyncopeClientFactoryBean clientFactory;
+
+ private SyncopeClient client;
+
+ private final SyncopeClient anonymousClient;
+
+ private final SyncopeTO syncopeTO;
+
+ private UserTO selfTO;
+
+ private final Map<Class<?>, Object> services = Collections.synchronizedMap(new HashMap<Class<?>, Object>());
+
+ public static SyncopeEnduserSession get() {
+ return (SyncopeEnduserSession) Session.get();
+ }
+
+ public SyncopeEnduserSession(final Request request) {
+ super(request);
+
+ // load properties from classpath file
+ loadProperties();
+
+ clientFactory = new SyncopeClientFactoryBean();
+ clientFactory.setAddress(new StringBuilder(scheme)
+ .append("://")
+ .append(host)
+ .append(":")
+ .append(port)
+ .append("/")
+ .append(rootPath)
+ .toString());
+ clientFactory.setContentType(SyncopeClientFactoryBean.ContentType.JSON);
+
+ anonymousClient = clientFactory.create(anonymousUser, anonymousKey);
+ syncopeTO = anonymousClient.getService(SyncopeService.class).info();
+
+ }
+
+ public boolean authenticate(final String username, final String password) {
+ boolean authenticated = false;
+
+ try {
+ client = clientFactory.setDomain(SyncopeConstants.MASTER_DOMAIN).create(username, password);
+
+ Pair<Map<String, Set<String>>, UserTO> self = client.self();
+ selfTO = self.getValue();
+
+ this.username = username;
+ this.password = password;
+ // bind explicitly this session to have a stateful behavior during http requests, unless session will expire
+ // for every request
+ this.bind();
+ authenticated = true;
+ } catch (Exception e) {
+ LOG.error("Authentication failed", e);
+ }
+
+ return authenticated;
+ }
+
+ public <T> void resetClient(final Class<T> service) {
+ T serviceInstance = getCachedService(service);
+ WebClient.client(serviceInstance).reset();
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> T getCachedService(final Class<T> serviceClass) {
+ T service;
+ if (services.containsKey(serviceClass)) {
+ service = (T) services.get(serviceClass);
+ } else {
+ service = client == null ? anonymousClient.getService(serviceClass) : client.getService(serviceClass);
+ services.put(serviceClass, service);
+ }
+
+ return service;
+ }
+
+ public <T> T getService(final Class<T> serviceClass) {
+ return getCachedService(serviceClass);
+ }
+
+ public <T> T getService(final String etag, final Class<T> serviceClass) {
+ T serviceInstance = getCachedService(serviceClass);
+ WebClient.client(serviceInstance).match(new EntityTag(etag), false).
+ type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
+
+ return serviceInstance;
+ }
+
+ public <T> T getService(final MediaType mediaType, final Class<T> serviceClass) {
+ T service;
+
+ synchronized (clientFactory) {
+ SyncopeClientFactoryBean.ContentType preType = clientFactory.getContentType();
+
+ clientFactory.setContentType(SyncopeClientFactoryBean.ContentType.fromString(mediaType.toString()));
+ service = clientFactory.create(username, password).getService(serviceClass);
+ clientFactory.setContentType(preType);
+ }
+
+ return service;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public String getRootPath() {
+ return rootPath;
+ }
+
+ public String getAnonymousUser() {
+ return anonymousUser;
+ }
+
+ public String getAnonymousKey() {
+ return anonymousKey;
+ }
+
+ public Boolean storePassword() {
+ return this.storePassword;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getLicense() {
+ return license;
+ }
+
+ public SyncopeTO getSyncopeTO() {
+ return syncopeTO;
+ }
+
+ public UserTO getSelfTO() {
+ return selfTO;
+ }
+
+ public boolean isAuthenticated() {
+ return getUsername() != null;
+ }
+
+ public DateFormat getDateFormat() {
+ final Locale locale = getLocale() == null ? Locale.ENGLISH : getLocale();
+
+ return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);
+ }
+
+ private void loadProperties() {
+ Properties properties = new Properties();
+
+ try {
+ properties.load(getClass().getResourceAsStream("/" + ENDUSER_PROPERTIES));
+ File enduserDir = new File(properties.getProperty("enduser.directory"));
+ if (enduserDir.exists() && enduserDir.canRead() && enduserDir.isDirectory()) {
+ File enduserDirProps = FileUtils.getFile(enduserDir, ENDUSER_PROPERTIES);
+ if (enduserDirProps.exists() && enduserDirProps.canRead() && enduserDirProps.isFile()) {
+ properties.clear();
+ properties.load(FileUtils.openInputStream(enduserDir));
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Error loading {} file", ENDUSER_PROPERTIES, e);
+// throw new WicketRuntimeException("Could not read " + ENDUSER_PROPERTIES, e);
+ }
+
+ this.scheme = properties.getProperty("scheme");
+ this.host = properties.getProperty("host");
+ this.port = properties.getProperty("port");
+ this.rootPath = properties.getProperty("rootPath");
+ this.anonymousUser = properties.getProperty("anonymousUser");
+ this.anonymousKey = properties.getProperty("anonymousKey");
+ this.storePassword = Boolean.valueOf(properties.getProperty("storePassword"));
+ version = properties.getProperty("version");
+ license = properties.getProperty("license");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
new file mode 100644
index 0000000..551555f
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.adapters;
+
+import org.apache.syncope.client.enduser.model.UserTORequest;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserTOAdapter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UserTOAdapter.class);
+
+ public UserTO fromUserTORequest(final UserTORequest userTORequest, final String oldSelfPassword) {
+
+ // adapter code, to be moved in a new utility class
+ final UserTO userTO = new UserTO();
+ // set key if in update mode
+ final Long key = userTORequest.getKey();
+ if (key != null) {
+ userTO.setKey(key);
+ }
+ // set username...
+ userTO.setUsername(userTORequest.getUsername());
+ // ...and password
+ String requestPassword = userTORequest.getPassword();
+ if (requestPassword == null || requestPassword.isEmpty()) {
+ userTO.setPassword(oldSelfPassword == null ? null : oldSelfPassword);
+ } else {
+ userTO.setPassword(requestPassword);
+ }
+
+ //set security question and answer
+ userTO.setSecurityQuestion(userTORequest.getSecurityQuestion());
+ userTO.setSecurityAnswer(userTORequest.getSecurityAnswer());
+ //set realm
+ userTO.setRealm(userTORequest.getRealm());
+ // add attributes
+ userTO.getPlainAttrs().addAll(userTORequest.getPlainAttrs().values());
+ userTO.getDerAttrs().addAll(userTORequest.getDerAttrs().values());
+ userTO.getVirAttrs().addAll(userTORequest.getVirAttrs().values());
+
+ return userTO;
+ }
+
+ public UserTORequest toUserTORequest(final UserTO userTO) {
+
+ final UserTORequest userTORequest = new UserTORequest().
+ key(userTO.getKey()).
+ username(userTO.getUsername()).
+ securityQuestion(userTO.getSecurityQuestion()).
+ securityAnswer(userTO.getSecurityAnswer()).
+ realm(userTO.getRealm());
+
+ userTORequest.getPlainAttrs().putAll(userTO.getPlainAttrMap());
+ userTORequest.getDerAttrs().putAll(userTO.getDerAttrMap());
+ userTORequest.getVirAttrs().putAll(userTO.getVirAttrMap());
+
+ return userTORequest;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java
new file mode 100644
index 0000000..68e3106
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Credentials {
+
+ private String username;
+
+ private String password;
+
+ public Credentials() {
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(final String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+ public Credentials username(final String username) {
+ this.username = username;
+ return this;
+ }
+
+ public Credentials password(final String password) {
+ this.password = password;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java
new file mode 100644
index 0000000..912f287
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.VirSchemaTO;
+
+public class SchemaResponse implements Serializable {
+
+ private static final long serialVersionUID = -8896862106241712829L;
+
+ private List<PlainSchemaTO> plainSchemas = new ArrayList<>();
+
+ private List<DerSchemaTO> derSchemas = new ArrayList<>();
+
+ private List<VirSchemaTO> virSchemas = new ArrayList<>();
+
+ public SchemaResponse() {
+ }
+
+ public List<PlainSchemaTO> getPlainSchemas() {
+ return plainSchemas;
+ }
+
+ public void setPlainSchemas(final List<PlainSchemaTO> plainSchemas) {
+ this.plainSchemas = plainSchemas;
+ }
+
+ public List<DerSchemaTO> getDerSchemas() {
+ return derSchemas;
+ }
+
+ public void setDerSchemas(final List<DerSchemaTO> derSchemas) {
+ this.derSchemas = derSchemas;
+ }
+
+ public List<VirSchemaTO> getVirSchemas() {
+ return virSchemas;
+ }
+
+ public void setVirSchemas(final List<VirSchemaTO> virSchemas) {
+ this.virSchemas = virSchemas;
+ }
+
+ public SchemaResponse plainSchemas(final List<PlainSchemaTO> value) {
+ this.plainSchemas = value;
+ return this;
+ }
+
+ public SchemaResponse derSchemas(final List<DerSchemaTO> value) {
+ this.derSchemas = value;
+ return this;
+ }
+
+ public SchemaResponse virSchemas(final List<VirSchemaTO> value) {
+ this.virSchemas = value;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
new file mode 100644
index 0000000..09bc219
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.model;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.syncope.common.lib.to.AttrTO;
+
+public class UserTORequest implements Serializable {
+
+ private static final long serialVersionUID = -6763020920564016374L;
+
+ private Long key;
+
+ private String username;
+
+ private String password;
+
+ private Long securityQuestion;
+
+ private String securityAnswer;
+
+ private String realm;
+
+ private Map<String, AttrTO> plainAttrs = new HashMap<>();
+
+ private Map<String, AttrTO> derAttrs = new HashMap<>();
+
+ private Map<String, AttrTO> virAttrs = new HashMap<>();
+
+ public UserTORequest() {
+ }
+
+ public Long getKey() {
+ return key;
+ }
+
+ public void setKey(final Long key) {
+ this.key = key;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(final String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+ public Long getSecurityQuestion() {
+ return securityQuestion;
+ }
+
+ public void setSecurityQuestion(final Long securityQuestion) {
+ this.securityQuestion = securityQuestion;
+ }
+
+ public String getSecurityAnswer() {
+ return securityAnswer;
+ }
+
+ public void setSecurityAnswer(final String securityAnswer) {
+ this.securityAnswer = securityAnswer;
+ }
+
+ public String getRealm() {
+ return realm;
+ }
+
+ public void setRealm(final String realm) {
+ this.realm = realm;
+ }
+
+ public Map<String, AttrTO> getPlainAttrs() {
+ return plainAttrs;
+ }
+
+ public void setPlainAttrs(final Map<String, AttrTO> plainAttrs) {
+ this.plainAttrs = plainAttrs;
+ }
+
+ public Map<String, AttrTO> getDerAttrs() {
+ return derAttrs;
+ }
+
+ public void setDerAttrs(final Map<String, AttrTO> derAttrs) {
+ this.derAttrs = derAttrs;
+ }
+
+ public Map<String, AttrTO> getVirAttrs() {
+ return virAttrs;
+ }
+
+ public void setVirAttrs(final Map<String, AttrTO> virAttrs) {
+ this.virAttrs = virAttrs;
+ }
+
+ public UserTORequest key(final Long value) {
+ this.key = value;
+ return this;
+ }
+
+ public UserTORequest username(final String value) {
+ this.username = value;
+ return this;
+ }
+
+ public UserTORequest password(final String value) {
+ this.password = value;
+ return this;
+ }
+
+ public UserTORequest securityQuestion(final Long value) {
+ this.securityQuestion = value;
+ return this;
+ }
+
+ public UserTORequest securityAnswer(final String value) {
+ this.securityAnswer = value;
+ return this;
+ }
+
+ public UserTORequest realm(final String value) {
+ this.realm = value;
+ return this;
+ }
+
+ public UserTORequest plainAttrs(final Map<String, AttrTO> value) {
+ this.plainAttrs = value;
+ return this;
+ }
+
+ public UserTORequest derAttrs(final Map<String, AttrTO> value) {
+ this.derAttrs = value;
+ return this;
+ }
+
+ public UserTORequest virAttrs(final Map<String, AttrTO> value) {
+ this.virAttrs = value;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java
new file mode 100644
index 0000000..4c5c07e
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.pages;
+
+import org.apache.wicket.NonResettingRestartException;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+public class HomePage extends WebPage {
+
+ private static final long serialVersionUID = -3422492668689122688L;
+
+ public HomePage(final PageParameters parameters) {
+ super(parameters);
+// throw new RedirectToUrlException("/app/");
+ throw new NonResettingRestartException("/app/");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
new file mode 100644
index 0000000..a3aedfc
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractBaseResource extends AbstractResource {
+
+ private static final long serialVersionUID = -7875801358718612782L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractBaseResource.class);
+
+ protected <T> T getService(final Class<T> serviceClass) {
+ return SyncopeEnduserSession.get().getService(serviceClass);
+ }
+
+ protected <T> T getService(final String etag, final Class<T> serviceClass) {
+ return SyncopeEnduserSession.get().getService(etag, serviceClass);
+ }
+
+ protected <T> void resetClient(final Class<T> serviceClass) {
+ SyncopeEnduserSession.get().resetClient(serviceClass);
+ }
+
+ protected boolean isSelfRegistrationAllowed() {
+ Boolean result = null;
+ try {
+ result = SyncopeEnduserSession.get().getSyncopeTO().isSelfRegAllowed();
+ } catch (SyncopeClientException e) {
+ LOG.error("While seeking if self registration is allowed", e);
+ }
+
+ return result == null
+ ? false
+ : result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java
new file mode 100644
index 0000000..bfceeab
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import javax.ws.rs.core.MediaType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Mirror REST resource for obtaining user self operations.
+ *
+ * @see org.apache.syncope.common.rest.api
+ */
+public class ErrorResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = -9184809392631523912L;
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ErrorResource.class);
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ ResourceResponse response = new ResourceResponse();
+ response.disableCaching();
+ response.setContentType(MediaType.APPLICATION_JSON);
+
+ response.setStatusCode(403);
+
+ return response;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
new file mode 100644
index 0000000..fa6fa8c
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.enduser.model.Credentials;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.util.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LoginResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = -7720997467070461915L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(LoginResource.class);
+
+ public LoginResource() {
+ }
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ int responseStatus;
+ final String responseMessage;
+ ResourceResponse response = new ResourceResponse();
+
+ try {
+ HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+ Credentials credentials = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()),
+ Credentials.class);
+ final String username = credentials.getUsername();
+ final String password = credentials.getPassword().isEmpty() ? null : credentials.getPassword();
+
+ LOG.debug("Enduser login, user: {}", username);
+
+ if (StringUtils.isBlank(username)) {
+ LOG.error("Could not read credentials from request: username is blank!");
+ responseMessage = "Could not read credentials from request: username is blank!";
+ responseStatus = 400;
+ } else {
+ // authenticate user
+ final boolean authenticated = SyncopeEnduserSession.get().authenticate(username, password);
+ responseStatus = authenticated ? 200 : 401;
+ responseMessage = username;
+ }
+
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(responseMessage);
+ }
+ });
+
+ } catch (Exception e) {
+ responseStatus = 400;
+ LOG.error("Could not read credentials from request", e);
+ }
+
+ response.setStatusCode(responseStatus);
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java
new file mode 100644
index 0000000..545b44d
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LogoutResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = -648841355644985051L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(LogoutResource.class);
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ LOG.debug("Enduser logout");
+
+ SyncopeEnduserSession.get().invalidate();
+
+ ResourceResponse response = new ResourceResponse();
+ response.setStatusCode(204);
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
new file mode 100644
index 0000000..544138b
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.client.enduser.model.SchemaResponse;
+import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.VirSchemaTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.apache.wicket.request.resource.IResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SchemaResource extends AbstractBaseResource {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SchemaResource.class);
+
+ private static final long serialVersionUID = 6453101466981543020L;
+
+ private final AnyTypeService anyTypeService;
+
+ private final AnyTypeClassService anyTypeClassService;
+
+ private final SchemaService schemaService;
+
+ public SchemaResource() {
+ anyTypeService = getService(AnyTypeService.class);
+ anyTypeClassService = getService(AnyTypeClassService.class);
+ schemaService = getService(SchemaService.class);
+ }
+
+ @Override
+ protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
+
+ AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
+
+ int responseStatus = 200;
+
+ try {
+
+ final AnyTypeTO anyTypeUserTO = anyTypeService.read(AnyTypeKind.USER.name());
+
+ final List<PlainSchemaTO> plainSchemas = new ArrayList<>();
+ final List<DerSchemaTO> derSchemas = new ArrayList<>();
+ final List<VirSchemaTO> virSchemas = new ArrayList<>();
+
+ // read all USER type schemas
+ for (String clazz : anyTypeUserTO.getClasses()) {
+ plainSchemas.addAll(getSchemaTOs(anyTypeClassService.read(clazz).getPlainSchemas(), SchemaType.PLAIN,
+ PlainSchemaTO.class));
+ derSchemas.addAll(getSchemaTOs(anyTypeClassService.read(clazz).getDerSchemas(), SchemaType.DERIVED,
+ DerSchemaTO.class));
+ virSchemas.addAll(getSchemaTOs(anyTypeClassService.read(clazz).getVirSchemas(), SchemaType.VIRTUAL,
+ VirSchemaTO.class));
+ }
+
+ response.setWriteCallback(new AbstractResource.WriteCallback() {
+
+ @Override
+ public void writeData(final IResource.Attributes attributes) throws IOException {
+ attributes.getResponse().write(POJOHelper.serialize(new SchemaResponse().
+ plainSchemas(plainSchemas).
+ derSchemas(derSchemas).
+ virSchemas(virSchemas)));
+ }
+ });
+
+ } catch (Exception e) {
+ LOG.error("Error retrieving " + AnyTypeKind.USER.name() + " class schemas", e);
+ responseStatus = 400;
+ }
+
+ response.setStatusCode(responseStatus);
+ return response;
+ }
+
+ private <T extends AbstractSchemaTO> List<T> getSchemaTOs(final List<String> schemaNames,
+ final SchemaType schemaType, final Class<T> type) {
+
+ List<T> schemaTOs = new ArrayList<>();
+
+ for (String schemaName : schemaNames) {
+ schemaTOs.add(type.cast(schemaService.read(schemaType, schemaName)));
+ }
+
+ return schemaTOs;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
new file mode 100644
index 0000000..f1ab6c8
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import java.util.List;
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.apache.wicket.request.resource.IResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SecurityQuestionResource extends AbstractBaseResource {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SecurityQuestionResource.class);
+
+ private static final long serialVersionUID = 6453101466981543020L;
+
+ private final SecurityQuestionService securityQuestionService;
+
+ public SecurityQuestionResource() {
+ securityQuestionService = getService(SecurityQuestionService.class);
+ }
+
+ @Override
+ protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
+
+ AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
+
+ int responseStatus = 200;
+
+ try {
+
+ LOG.debug("List available security questions");
+
+ final List<SecurityQuestionTO> securityQuestionTOs = securityQuestionService.list();
+
+ response.setWriteCallback(new AbstractResource.WriteCallback() {
+
+ @Override
+ public void writeData(final IResource.Attributes attributes) throws IOException {
+ attributes.getResponse().write(POJOHelper.serialize(securityQuestionTOs));
+ }
+ });
+
+ } catch (Exception e) {
+ LOG.error("Error retrieving security questions", e);
+ responseStatus = 400;
+ }
+
+ response.setStatusCode(responseStatus);
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
new file mode 100644
index 0000000..61734a7
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.enduser.adapters.UserTOAdapter;
+import org.apache.syncope.client.enduser.model.UserTORequest;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.util.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserSelfCreateResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = -2721621682300247583L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(UserSelfCreateResource.class);
+
+ private final UserSelfService userSelfService;
+
+ private final UserTOAdapter userTOAdapter;
+
+ public UserSelfCreateResource() {
+ userTOAdapter = new UserTOAdapter();
+ userSelfService = getService(UserSelfService.class);
+ }
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ int responseStatus = 200;
+ final StringBuilder responseMessage = new StringBuilder();
+ ResourceResponse response = new ResourceResponse();
+
+ try {
+ HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+
+ final UserTORequest userTORequest = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()),
+ UserTORequest.class);
+
+ if (isSelfRegistrationAllowed() && userTORequest != null) {
+ LOG.debug("Received user self registration request for user: [{}]", userTORequest.getUsername());
+ LOG.trace("Received user self registration request is: [{}]", userTORequest);
+ // adapt request and create user
+ userSelfService.create(userTOAdapter.fromUserTORequest(userTORequest, null),
+ SyncopeEnduserSession.get().storePassword());
+ responseMessage.append("User").append(userTORequest.getUsername()).append("created successfully");
+ } else {
+ responseMessage.append(userTORequest == null
+ ? "Request received is not valid"
+ : "Self registration not allowed");
+ responseStatus = 403;
+ }
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(responseMessage);
+ }
+ });
+
+ } catch (final Exception e) {
+ responseStatus = 400;
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(e.getMessage());
+ }
+ });
+ LOG.error("Could not read userTO from request", e);
+ }
+
+ response.setStatusCode(responseStatus);
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
new file mode 100644
index 0000000..3519e78
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.enduser.adapters.UserTOAdapter;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Mirror REST resource for obtaining user self operations.
+ *
+ * @see org.apache.syncope.common.rest.api
+ */
+public class UserSelfReadResource extends AbstractResource {
+
+ private static final long serialVersionUID = -9184809392631523912L;
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(UserSelfReadResource.class);
+
+ private final UserTOAdapter userTOAdapter;
+
+ public UserSelfReadResource() {
+ userTOAdapter = new UserTOAdapter();
+ }
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ ResourceResponse response = new ResourceResponse();
+ final String selfTOJson = POJOHelper.serialize(userTOAdapter.toUserTORequest(SyncopeEnduserSession.get().
+ getSelfTO()));
+
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(selfTOJson);
+ }
+ });
+
+ return response;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
new file mode 100644
index 0000000..5fc9c82
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.enduser.adapters.UserTOAdapter;
+import org.apache.syncope.client.enduser.model.UserTORequest;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.util.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserSelfUpdateResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = -2721621682300247583L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(UserSelfUpdateResource.class);
+
+ private final UserSelfService userSelfService;
+
+ private final UserTOAdapter userTOAdapter;
+
+ public UserSelfUpdateResource() {
+ userTOAdapter = new UserTOAdapter();
+ userSelfService = getService(UserSelfService.class);
+ }
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ int responseStatus = 200;
+ final String responseMessage;
+ ResourceResponse response = new ResourceResponse();
+
+ try {
+ HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+
+ final UserTORequest userTOResponse = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()),
+ UserTORequest.class);
+
+ LOG.debug("userTOResponse: {}", userTOResponse);
+
+ // adapt user, change self password only value passed is not null and has changed
+ UserTO userTO = userTOAdapter.fromUserTORequest(userTOResponse, SyncopeEnduserSession.get().getPassword());
+
+ LOG.debug("Enduser user self update, user: {}", userTO.toString());
+
+ // update user
+ userSelfService.update(userTO);
+ responseMessage = "User updated successfully";
+
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(responseMessage);
+ }
+ });
+
+ } catch (final Exception e) {
+ responseStatus = 400;
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(e.getMessage());
+ }
+ });
+ LOG.error("Could not read userTO from request", e);
+ }
+
+ response.setStatusCode(responseStatus);
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/css/app.css
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/app.css b/client/enduser/src/main/resources/META-INF/resources/app/css/app.css
new file mode 100644
index 0000000..e5ae8e5
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/css/app.css
@@ -0,0 +1,28 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* app general css stylesheet */
+
+.growl-container > .growl-item.ng-enter,
+.growl-container > .growl-item.ng-leave {
+ -webkit-transition:1s linear all;
+ -moz-transition:1s linear all;
+ -o-transition:1s linear all;
+ transition:1s linear all;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css b/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css
new file mode 100644
index 0000000..ee13bd0
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css
@@ -0,0 +1,253 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#form-container {
+ position: relative;
+ width: 100%;
+ margin: 0 auto;
+ text-align: center;
+}
+
+#form-container .page-header { background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
+ margin: 1% 16%;
+ width: 72%; padding:10px;
+ /* shadows and rounded borders */
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+ box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+}
+#form-container .breadcrumb-header {
+ margin: 1% 16%;
+ width: 72%; padding:10px;
+}
+
+.signup-form {
+ text-align: left;
+ padding: 2%;
+}
+
+#attribute {
+ padding: 0 255px;
+}
+
+#attribute-derived,
+#attribute-virtual {
+ padding: 0 155px;
+}
+
+.attribute-virtual-value-container {
+ margin-top: 2%;
+ list-style: none;
+ padding-right: 5%;
+}
+
+.attribute-virtual-value-field {
+ font-weight: 700;
+ padding: 6px 12px;
+ margin-bottom: 2%;
+}
+
+.minus{
+ margin-bottom: 2%;
+}
+
+.fileButton{
+ margin-top: 2%;
+}
+
+.upper-select {
+ padding-right: 71%;
+ padding-left: 18%;
+}
+
+.attribute-ui-select {
+ width: 100%;
+ padding-right: 7%;
+ padding-left: 7%;
+}
+
+#previous {
+ background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
+ float: left;
+ color: black;
+ width: 30%;
+}
+#previous:hover {
+ background: #658D5D;
+}
+
+#next{
+ background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
+ margin-top: 5px;
+ float: right;
+ color: black;
+ width: 30%;
+}
+#next:hover {
+ background: #658D5D;
+}
+
+#save{
+ background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
+ color: black;
+ margin-top: 5%;
+ width: 15%;
+}
+#save:hover {
+ background: #658D5D;
+}
+#cancel {
+ margin-top: 5%;
+ width: 15%;
+}
+
+#form-views { width:auto; }
+
+/* basic styling for entering and leaving */
+/* left and right to add to ensure full width: position:absolute; left:30px; right:30px; */
+#form-views.ng-enter,
+#form-views.ng-leave {
+ transition:0.5s all ease; -moz-transition:0.5s all ease; -webkit-transition:0.5s all ease;
+}
+
+/* enter animation */
+#form-views.ng-enter {
+ -webkit-animation:slideInRight 0.5s both ease;
+ -moz-animation:slideInRight 0.5s both ease;
+ animation:slideInRight 0.5s both ease;
+}
+
+/* leave animation */
+#form-views.ng-leave {
+ -webkit-animation:slideOutLeft 0.5s both ease;
+ -moz-animation:slideOutLeft 0.5s both ease;
+ animation:slideOutLeft 0.5s both ease;
+}
+
+/** Button breadcrumb **/
+.btn-breadcrumb .btn:not(:last-child):after {
+ content: " ";
+ display: block;
+ width: 0;
+ height: 0;
+ border-top: 17px solid transparent;
+ border-bottom: 17px solid transparent;
+ border-left: 10px solid white;
+ position: absolute;
+ top: 50%;
+ margin-top: -17px;
+ left: 100%;
+ z-index: 3;
+}
+.btn-breadcrumb .btn:not(:last-child):before {
+ content: " ";
+ display: block;
+ width: 0;
+ height: 0;
+ border-top: 17px solid transparent;
+ border-bottom: 17px solid transparent;
+ border-left: 10px solid rgb(173, 173, 173);
+ position: absolute;
+ top: 50%;
+ margin-top: -17px;
+ margin-left: 1px;
+ left: 100%;
+ z-index: 3;
+}
+
+/** The Spacing **/
+.btn-breadcrumb .btn {
+ padding:6px 12px 6px 24px;
+}
+.btn-breadcrumb .btn:first-child {
+ padding:6px 6px 6px 10px;
+}
+.btn-breadcrumb .btn:last-child {
+ padding:6px 18px 6px 24px;
+}
+
+/** Default button **/
+.btn-breadcrumb .btn.btn-default:not(:last-child):after {
+ border-left: 10px solid #fff;
+}
+.btn-breadcrumb .btn.btn-default:not(:last-child):before {
+ border-left: 10px solid #ccc;
+}
+.btn-breadcrumb .btn.btn-default:hover:not(:last-child):after {
+ border-left: 10px solid #ebebeb;
+}
+.btn-breadcrumb .btn.btn-default:hover:not(:last-child):before {
+ border-left: 10px solid #adadad;
+}
+
+.breadcrumb-disabled-link {
+ pointer-events: none;
+ cursor: default;
+}
+
+.text-validation-error{
+ color: #dd301b;
+ font-weight: 600;
+}
+/* ANIMATIONS
+============================================================================= */
+/* slide out to the left */
+@keyframes slideOutLeft {
+ to { transform: translateX(-200%); }
+}
+@-moz-keyframes slideOutLeft {
+ to { -moz-transform: translateX(-200%); }
+}
+@-webkit-keyframes slideOutLeft {
+ to { -webkit-transform: translateX(-200%); }
+}
+
+/* slide in from the right */
+@keyframes slideInRight {
+ from { transform:translateX(200%); }
+ to { transform: translateX(0); }
+}
+@-moz-keyframes slideInRight {
+ from { -moz-transform:translateX(200%); }
+ to { -moz-transform: translateX(0); }
+}
+@-webkit-keyframes slideInRight {
+ from { -webkit-transform:translateX(200%); }
+ to { -webkit-transform: translateX(0); }
+}
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/css/login.css
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/login.css b/client/enduser/src/main/resources/META-INF/resources/app/css/login.css
new file mode 100644
index 0000000..fdc9e3e
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/css/login.css
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+body, html {
+ margin: 45px 0;
+ height: 100%;
+ background-repeat: no-repeat;
+ /*background-image: linear-gradient(rgb(104, 145, 162), #00a65a);*/
+ background-color: #EEEEEE;
+}
+#login-container {
+ position: relative;
+ width: 100%;
+ margin: 0 auto;
+ text-align: center;
+ background-color: #FFF;
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.65);
+ box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.65);
+}
+#login-container .row > div {
+ margin-bottom: 1em;
+}
+#login-container .row > div:last-child {
+ margin-bottom: 0;
+}
+#login-container #logo {
+ position: relative;
+ float: left;
+ margin-left: 15%;
+ border-top-right-radius: 100px;
+ border-top-left-radius: 100px;
+ border-bottom-right-radius: 100px;
+ border-bottom-left-radius: 100px;
+}
+
+#login-container #language{
+ padding: 0px;
+ height: 40px;
+}
+
+#login-container #signup-btn {
+ padding-top: 15px;
+ padding-bottom: 15px;
+}
+#login-container #signup-btn:hover {
+ background-color: #1d1d1d;
+ border-color: #181818;
+}
+
+.login-btn {
+ background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */
+ margin-top: 5px;
+ color: black;
+}
+.login-btn:hover {
+ background: #658D5D;
+}
+
+#login {
+ position: relative;
+ padding: 25px 25px 50px 25px;
+ margin-bottom: 1em;
+}
+#login #login-form {
+ margin-top: 2em;
+ margin-bottom: 2em;
+ text-align: left;
+}
+#login-form{
+ padding: 0 195px;
+ margin: 7%;
+}
+#languageContainer {
+ padding: 0 25px;
+}
+
+.logout{
+ float: right;
+}
\ No newline at end of file
[4/4] syncope git commit: This closes #11
Posted by an...@apache.org.
This closes #11
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/714557e6
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/714557e6
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/714557e6
Branch: refs/heads/master
Commit: 714557e64f309bd4975ed55bb7d182a7727c4667
Parents: 223a64e
Author: Andrea Patricelli <an...@tirasa.net>
Authored: Fri Oct 30 10:31:21 2015 +0100
Committer: Andrea Patricelli <an...@tirasa.net>
Committed: Fri Oct 30 10:31:21 2015 +0100
----------------------------------------------------------------------
pom.xml | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/714557e6/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a5ee74a..f4482f6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1079,7 +1079,6 @@ under the License.
<version>${FileSaver.version}</version>
</dependency>
-
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>